﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-牵着老婆满街逛-随笔分类-C++</title><link>http://www.cppblog.com/tx7do/category/2349.html</link><description>严以律己,宽以待人. 三思而后行.&lt;/br&gt;
GMail/GTalk: yanglinbo#google.com;&lt;/br&gt;
MSN/Email: tx7do#yahoo.com.cn;&lt;/br&gt;
QQ: 3 0 3 3 9 6 9 2 0 .</description><language>zh-cn</language><lastBuildDate>Sun, 01 Jan 2017 11:33:00 GMT</lastBuildDate><pubDate>Sun, 01 Jan 2017 11:33:00 GMT</pubDate><ttl>60</ttl><item><title>VS2015编译Android版Cocos项目所踩的那些坑</title><link>http://www.cppblog.com/tx7do/archive/2017/01/01/214569.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Sun, 01 Jan 2017 06:40:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2017/01/01/214569.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/214569.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2017/01/01/214569.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/214569.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/214569.html</trackback:ping><description><![CDATA[微软现在已经越来越变态了,简直万能了.彻底的拥抱了开源.<br />
比如,Windows10下直接把Ubuntu变成了子系统(不是基于虚拟机,基于容器),用起来就跟CMD一样!<br />
比如,VS2015直接支持Android的编译打包.<br />
说实话,就目前来说,VS的学习成本是最低的,虽然现在Android Studio 2.2已经支持了CMake编译NDK原生代码了,但是Gradle,Ant,NDK这些学习成本太高,弄起来也稍微有点复杂,特别是,国内把谷歌墙了的情况下,它又非常的依赖网络.<br />
我用惯了VS,VS+VA真是天生绝配.我要说明的是,我VIM也用得挺溜的,就算是开发linux程序,我编码还是用的VS(VS+Samba+SSH).以前想,如果VS能提供全套服务,那该多好.如今,这个梦想实现了.<br />
<br />
我的工程基础来自于这篇文章:<a href="https://blogs.msdn.microsoft.com/vcblog/2016/07/12/cocos2d-x-visual-studio-android-project/" title="Cocos2d-x Visual Studio Android Project">Cocos2d-x Visual Studio Android Project</a><br />
下载下来,然后按照教程里面一二三的做,经过了编译的等待之后,成功的打包出apk,烧到手机上,也毫无问题的运行成功.<br />
<br />
这看起来是很完美,但是,它是把cocos引擎代码放在so里面跟游戏代码一起编译的,真要搞起来,编译cocos就要搞死人,这很坑.<br />
很显然,我需要把cocos提取出来编译成单独的一个静态库.a.<br />
我拿so文件稍作修改,改出了一个cocos引擎的静态库工程,然后编译,一切都很顺利,很正常.<br />
然而,编译so项目的时候,幺蛾子出现!<br />
出现无数的undefined referenced错误,通常来说,这都是没有引用静态库导致的未找到实现代码的错误.<br />
可是,问题是我已经引用了所有的.a文件了,然后我纳闷了很久.<br />
突然一激灵:<strong style="color: red;">gcc的链接器对ld链接的文件是有顺序要求的!</strong><br />
因为我用VS引用.lib从来没有说有这样的顺序问题.以为它对gcc也一样,然而并没有.<br />
我立马根据依赖关系,调整了引用的顺序.(o゜&#9661;゜)o&#9734;[BINGO!]果然OK了!<br />
<br />
我看了apk,比之前那个少了一半的大小,想着静态库的话,动态库是选择性的把代码链接进去,而没用的代码抛去.想着应该没啥问题,于是就兴冲冲的烧进手机,结果懵逼了,crash了!<br />
赶紧的VS开USB真机调试,然后我就懵逼了:jni的入口方法:JNI_OnLoad没有被调用!<br />
难道没有被导出?这不应该吧?只能用nm命令查看下了.<br />
这时候,Windows10的子系统Ubuntu就派上了大大的用场了.我Win+R-&gt;bash,启动了Ubuntu,然后输入命令查看:<br />
<img src="http://www.cppblog.com/images/cppblog_com/tx7do/vs2015_android_nm_jnionload.png" width="1348" height="40" alt="" /><br />
尼玛,果然!!!<br />
我接着,试着在so里面直接模拟调用了JNI_OnLoad,没问题,调试进去了.a里面的代码块,也就是说,链接进去了,但是,并没有将之导出.哪怕我强制性的设置其可见性,也是没用的:<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->__attribute__&nbsp;((visibility&nbsp;("default")))&nbsp;jint&nbsp;JNI_OnLoad(JavaVM&nbsp;*vm,&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;*reserved)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;JniHelper::setJavaVM(vm);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;cocos_android_app_init(JniHelper::getEnv());<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;JNI_VERSION_1_4;<br />
}</div>
我再一次懵逼了.
<br />
如果是这样,那么恐怕只有完整的链接到so才能解决问题了.<br />
我在so工程的 链接器-&gt;高级 里面找到了"整个存档"这个选项,或许就是它了,我把它设置成:<br />
<img src="http://www.cppblog.com/images/cppblog_com/tx7do/vs2015_android_linker_wholearchive.png" width="569" height="32" alt="" /><br />
然后把so工程重编译了,看了下,so的大小这时候跟最早没拆分的版本一样大了.<br />
烧进真机一调试,果然就没问题了.<br />
虽然这当中折腾了我不少时间和精力,但是相对来说,VS不算折腾了.<br /><br />另外，资源只是放在assets里面，还不够的，还需要在工程里面引用才可以，这点有点坑。<br />
<br />
<strong>
开发环境</strong><br />
<div>VS2015 Update3</div>
<div>cocos2d-x-3.13.</div>
<div>apache-ant-1.9.7</div>
<div>jdk1.8.0_112</div>
<div>android-ndk-r13b</div>
<br /><strong>下载</strong><br />cocos引擎静态库工程文件,请将其解压放置在$COCOS_ROOT()/build下,静态库.a文件生成在$COCOS_ROOT()/lib下:<a href="/Files/tx7do/libcocos2d-android.zip">/Files/tx7do/libcocos2d-android.zip</a><br />HelloWorld示例工程文件:<a href="/Files/tx7do/proj.visualstudio.zip">/Files/tx7do/proj.visualstudio.zip</a><br /><br /><div><strong>参考资料</strong><br /><a href="https://blogs.msdn.microsoft.com/vcblog/2016/07/12/cocos2d-x-visual-studio-android-project/" title="Cocos2d-x Visual Studio Android Project">Cocos2d-x Visual Studio Android Project</a></div><a href="http://www.jb51.net/LINUXjishu/236871.html" title="Linux系统下 连接器ld链接顺序的总结">Linux系统下 连接器ld链接顺序的总结</a><br /><a href="http://www.voidcn.com/blog/xiaoheiyohehe/article/p-2867801.html" title="我所理解的jni与ndk">我所理解的jni与ndk</a><img src ="http://www.cppblog.com/tx7do/aggbug/214569.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2017-01-01 14:40 <a href="http://www.cppblog.com/tx7do/archive/2017/01/01/214569.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux使用msgpack及测试</title><link>http://www.cppblog.com/tx7do/archive/2014/05/29/207141.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Thu, 29 May 2014 01:16:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2014/05/29/207141.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/207141.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2014/05/29/207141.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/207141.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/207141.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 转载自：http://blog.csdn.net/sunny3106/article/details/7375907在网络程序的开发中，免不了会涉及到服务器与客户端之间的协议交互，由于客户端与服务器端的平台的差异性（有可能是windows，android，linux等等），以及网络字节序等问题，通信包一般会做序列化与反序列化的处理，也就是通常说的打包解包工作。google的protobuf是一...&nbsp;&nbsp;<a href='http://www.cppblog.com/tx7do/archive/2014/05/29/207141.html'>阅读全文</a><img src ="http://www.cppblog.com/tx7do/aggbug/207141.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2014-05-29 09:16 <a href="http://www.cppblog.com/tx7do/archive/2014/05/29/207141.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>msgpack[C++]使用笔记 和 msgpack/cPickle性能对比</title><link>http://www.cppblog.com/tx7do/archive/2014/05/29/207140.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Thu, 29 May 2014 01:15:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2014/05/29/207140.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/207140.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2014/05/29/207140.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/207140.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/207140.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 转载自：http://blog.csdn.net/xiarendeniao/article/details/6801338python版本msgpack安装：wget http://pypi.python.org/packages/source/m/msgpack-python/msgpack-python-0.1.9.tar.gzpython2.x setup.py install ...&nbsp;&nbsp;<a href='http://www.cppblog.com/tx7do/archive/2014/05/29/207140.html'>阅读全文</a><img src ="http://www.cppblog.com/tx7do/aggbug/207140.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2014-05-29 09:15 <a href="http://www.cppblog.com/tx7do/archive/2014/05/29/207140.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Twitter Snowflake</title><link>http://www.cppblog.com/tx7do/archive/2014/05/29/207139.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Wed, 28 May 2014 18:03:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2014/05/29/207139.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/207139.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2014/05/29/207139.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/207139.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/207139.html</trackback:ping><description><![CDATA[<div><strong style="color: red">转载自：</strong><a style="color: red" href="http://blog.yxwang.me/2012/08/twitter-snowflake/"><strong>http://blog.yxwang.me/2012/08/twitter-snowflake/</strong></a><br /><br />
<div style="border-bottom: 0px; border-left: 0px; padding-bottom: 0px; text-transform: none; background-color: rgb(248,248,248); text-indent: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font: 18px/27px 'Open Sans', 'Hiragino Sans GB', 'Helvetica Neue', 微软雅黑, serif; white-space: normal; letter-spacing: normal; color: rgb(34,34,34); vertical-align: baseline; border-top: 0px; border-right: 0px; word-spacing: 0px; padding-top: 0px; -webkit-text-stroke-width: 0px" class="entry-content">
<p style="border-bottom: 0px; border-left: 0px; padding-bottom: 0px; margin: 0px 0px 1.5em; padding-left: 0px; padding-right: 0px; font-family: inherit; font-size: 18px; vertical-align: baseline; border-top: 0px; border-right: 0px; padding-top: 0px">这是一篇两年前 Twitter 开发团队写的文章，今天挖出来研究了一下。原文地址<span class="Apple-converted-space">&nbsp;</span><a style="border-bottom: 0px; border-left: 0px; padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: inherit; word-wrap: break-word; white-space: pre-wrap; color: rgb(117,21,144); font-size: 18px; vertical-align: baseline; border-top: 0px; border-right: 0px; padding-top: 0px; -webkit-transition: color 0.3s; transition: color 0.3s" href="http://engineering.twitter.com/2010/06/announcing-snowflake.html">http://engineering.twitter.com/2010/06/announcing-snowflake.html</a></p>
<p style="border-bottom: 0px; border-left: 0px; padding-bottom: 0px; margin: 0px 0px 1.5em; padding-left: 0px; padding-right: 0px; font-family: inherit; font-size: 18px; vertical-align: baseline; border-top: 0px; border-right: 0px; padding-top: 0px">Twitter 早期用 MySQL 存储数据，随着用户的增长，单一的 MySQL 实例没法承受海量的数据，开发团队就开始用<span class="Apple-converted-space">&nbsp;</span><a style="border-bottom: 0px; border-left: 0px; padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: inherit; word-wrap: break-word; white-space: pre-wrap; color: rgb(117,21,144); font-size: 18px; vertical-align: baseline; border-top: 0px; border-right: 0px; padding-top: 0px; -webkit-transition: color 0.3s; transition: color 0.3s" href="http://cassandra.apache.org/">Cassandra</a><span class="Apple-converted-space">&nbsp;</span>和 sharded MySQL 替代原有的系统。然而和 MySQL 不同的是，Cassandra 没有内置为每一条数据生成唯一 ID 的功能，因为在一个分布式环境下，很难有完美的 ID 生成方案。</p>
<p style="border-bottom: 0px; border-left: 0px; padding-bottom: 0px; margin: 0px 0px 1.5em; padding-left: 0px; padding-right: 0px; font-family: inherit; font-size: 18px; vertical-align: baseline; border-top: 0px; border-right: 0px; padding-top: 0px">对于 Twitter 而言，这样的 ID 生成方案要满足两个基本的要求，一是每秒能生成几十万条 ID 用于标识不同的 tweet；二是这些 ID 应该可以有个大致的顺序，也就是说发布时间相近的两条 tweet，它们的 ID 也应当相近，这样才能方便各种客户端对 tweet 进行排序。</p>
<p style="border-bottom: 0px; border-left: 0px; padding-bottom: 0px; margin: 0px 0px 1.5em; padding-left: 0px; padding-right: 0px; font-family: inherit; font-size: 18px; vertical-align: baseline; border-top: 0px; border-right: 0px; padding-top: 0px">第一个要求意味着 ID 生成要以一种非协作的（uncoordinated）的方式进行，例如不能有一个全局的原子变量。</p>
<p style="border-bottom: 0px; border-left: 0px; padding-bottom: 0px; margin: 0px 0px 1.5em; padding-left: 0px; padding-right: 0px; font-family: inherit; font-size: 18px; vertical-align: baseline; border-top: 0px; border-right: 0px; padding-top: 0px">第二个要求使得 tweet 按 ID 排序后满足<span class="Apple-converted-space">&nbsp;</span><a style="border-bottom: 0px; border-left: 0px; padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: inherit; word-wrap: break-word; white-space: pre-wrap; color: rgb(117,21,144); font-size: 18px; vertical-align: baseline; border-top: 0px; border-right: 0px; padding-top: 0px; -webkit-transition: color 0.3s; transition: color 0.3s" href="http://ci.nii.ac.jp/naid/110002673489/">k-sorted</a><span class="Apple-converted-space">&nbsp;</span>条件。如果序列 A 要满足 k-sorted，当且仅当对于任意的 p, q，如果 1 &lt;= p &lt;= q - k (1 &lt;= p &lt;= q &lt;= n)，则有 A[p] &lt;= A[q]。换句话说，如果元素 p 排在 q 前面，且相差至少 k 个位置，那么 p 必然小于或等于 q。如果 tweet 序列满足这个条件，要获取第 r 条 tweet 之后的消息，只要从第 r - k 条开始查找即可。</p>
<p style="border-bottom: 0px; border-left: 0px; padding-bottom: 0px; margin: 0px 0px 1.5em; padding-left: 0px; padding-right: 0px; font-family: inherit; font-size: 18px; vertical-align: baseline; border-top: 0px; border-right: 0px; padding-top: 0px">Twitter 解决这两个问题的方案非常简单高效：每一个 ID 都是 64 位数字，由时间戳、节点号和序列编号组成。其中序列编号是每个节点本地生成的序号，而节点号则由<span class="Apple-converted-space">&nbsp;</span><a style="border-bottom: 0px; border-left: 0px; padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: inherit; word-wrap: break-word; white-space: pre-wrap; color: rgb(117,21,144); font-size: 18px; vertical-align: baseline; border-top: 0px; border-right: 0px; padding-top: 0px; -webkit-transition: color 0.3s; transition: color 0.3s" href="http://zookeeper.apache.org/">ZooKeeper</a><span class="Apple-converted-space">&nbsp;</span>维护。</p>
<p style="border-bottom: 0px; border-left: 0px; padding-bottom: 0px; margin: 0px 0px 1.5em; padding-left: 0px; padding-right: 0px; font-family: inherit; font-size: 18px; vertical-align: baseline; border-top: 0px; border-right: 0px; padding-top: 0px">具体的参数可以在这个<span class="Apple-converted-space">&nbsp;</span><a style="border-bottom: 0px; border-left: 0px; padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: inherit; word-wrap: break-word; white-space: pre-wrap; color: rgb(117,21,144); font-size: 18px; vertical-align: baseline; border-top: 0px; border-right: 0px; padding-top: 0px; -webkit-transition: color 0.3s; transition: color 0.3s" href="https://github.com/twitter/snowflake/blob/master/src/main/scala/com/twitter/service/snowflake/IdWorker.scala">IdWorker.scala</a><span class="Apple-converted-space">&nbsp;</span>中看到。序列编号有 12 位，意味着每个节点在每毫秒可以产生 4096 个 ID。节点号在源码中被分成两部分，数据中心的 ID 和节点 ID，各自占 5 位。时间戳则是记录了从 1288834974657 (Thu, 04 Nov 2010 01:42:54 GMT) 这一时刻到当前时间所经过的毫秒数，占 41 位（还有一位是符号位，永远为 0）。</p></div></div><img src ="http://www.cppblog.com/tx7do/aggbug/207139.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2014-05-29 02:03 <a href="http://www.cppblog.com/tx7do/archive/2014/05/29/207139.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>网游服务器中的GUID(唯一标识码)实现-基于snowflake算法</title><link>http://www.cppblog.com/tx7do/archive/2014/05/29/207138.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Wed, 28 May 2014 17:33:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2014/05/29/207138.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/207138.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2014/05/29/207138.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/207138.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/207138.html</trackback:ping><description><![CDATA[<div><strong style="color: red">转载自：</strong><a style="color: red" href="http://www.cppfans.org/1623.html"><strong>http://www.cppfans.org/1623.html</strong></a><br /><br /><article style="position: relative; text-align: left; padding-bottom: 5px; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; padding-left: 20px; padding-right: 20px; display: block; font: 14px/25px 'Microsoft Yahei', 'Helvetica Neue', Helvetica, Arial, sans-serif; word-wrap: break-word; white-space: normal; letter-spacing: normal; color: rgb(85,85,85); word-break: break-all; word-spacing: 0px; padding-top: 20px; -webkit-text-stroke-width: 0px" class="article-content"> 
<p style="margin: 0px 0px 15px">本文中的算法采用twitter的snowflake算法，具体请搜索介绍，原来是用Scala写的，因我项目需要，改写成C++语言，主要用于高效的生成唯一的ID, 核心算法就是毫秒级时间(41位)+机器ID(10位)+毫秒内序列(12位).</p>
<p style="margin: 0px 0px 15px">网上也有好多PHP写的插件模块，核心用了网络通讯将生成的ID发送给PHP使用，没深入研究PHP的模块写法。</p>
<p style="margin: 0px 0px 15px">废话不多说了，还是直接上代码好了。</p>
<p style="margin: 0px 0px 15px">uuid.h</p><pre style="border-bottom: medium none; border-left: medium none; padding-bottom: 10px; margin: 20px 0px; padding-left: 20px; padding-right: 20px; display: block; font: 12px/20px 'courier new'; word-wrap: break-word; white-space: pre-wrap;background: rgb(74,74,74); color: rgb(248,248,212); word-break: break-all; border-top: medium none; border-right: medium none; padding-top: 10px; border-top-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius: 2px; border-bottom-left-radius: 2px">#ifndef __UTIL_UUID_H__
#define __UTIL_UUID_H__

#include &lt;stdint.h&gt;

namespace utils
{
// twitter snowflake算法
// 64       63--------------22---------12---------0
// 符号位   |     41位时间   |10位机器码|12位自增码|
extern uint64_t get_time();

class unique_id_t
{
public:
    unique_id_t();
    ~unique_id_t();

    void set_epoch(uint64_t epoch);
    void set_machine(int32_t machine);
    int64_t generate();

private:
    uint64_t epoch_;
    uint64_t time_;
    int32_t machine_;
    int32_t sequence_;
};

}

#endif // !__UTIL_UUID_H__</pre>
<p style="margin: 0px 0px 15px">uuid.cpp</p><pre style="border-bottom: medium none; border-left: medium none; padding-bottom: 10px; margin: 20px 0px; padding-left: 20px; padding-right: 20px; display: block; font: 12px/20px 'courier new'; word-wrap: break-word; white-space: pre-wrap;background: rgb(74,74,74); color: rgb(248,248,212); word-break: break-all; border-top: medium none; border-right: medium none; padding-top: 10px; border-top-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius: 2px; border-bottom-left-radius: 2px">#include "uuid.h"
#if defined(__GUNC__)
#include &lt;sys/time.h&gt;
#include &lt;unistd.h&gt;
#define EPOCHFILETIME 11644473600000000ULL
#else
#include &lt;windows.h&gt;
#include &lt;time.h&gt;
#define EPOCHFILETIME 11644473600000000Ui64
#endif

namespace utils
{
    uint64_t get_time()
    {
#ifdef __GUNC__
        struct timeval tv;
        gettimeofday(&amp;tv, NULL);
        uint64 time = tv.tv_usec;
        time /= 1000;
        time += (tv.tv_sec * 1000);
        return time;
#else
        FILETIME filetime;
        uint64_t time = 0;
        GetSystemTimeAsFileTime(&amp;filetime);

        time |= filetime.dwHighDateTime;
        time &lt;&lt;= 32;
        time |= filetime.dwLowDateTime;

        time /= 10;
        time -= EPOCHFILETIME;
        return time / 1000;
#endif
    }

    unique_id_t::unique_id_t()
    {
        epoch_ = 0;
        time_ = 0;
        machine_ = 0;
        sequence_ = 0;
    }

    unique_id_t::~unique_id_t()
    {

    }

    void unique_id_t::set_epoch(uint64_t epoch)
    {
        epoch_ = epoch;
    }

    void unique_id_t::set_machine(int32_t machine)
    {
        machine_ = machine;
    }

    int64_t unique_id_t::generate()
    {
        int64_t value = 0;
        uint64_t time = get_time() - epoch_;

        // 保留后41位时间
        value = time &lt;&lt; 22;

        // 中间10位是机器ID
        value |= (machine_ &amp; 0x3FF) &lt;&lt; 12;

        // 最后12位是sequenceID
        value |= sequence_++ &amp; 0xFFF;
        if (sequence_ == 0x1000)
        {
            sequence_ = 0;
        }

        return value;
    }
}

#ifdef __TEST__
#include &lt;iostream&gt;
void test()
{
    utils::unique_id_t* u_id_ptr = new utils::unique_id_t();
    u_id_ptr-&gt;set_epoch(uint64_t(1367505795100));
    u_id_ptr-&gt;set_machine(int32_t(100));
    for (int i = 0; i &lt; 1024; ++i)
    {
        std::cout &lt;&lt; u_id_ptr-&gt;generate() &lt;&lt; std::endl;;
    }
}
#endif</pre>
<p style="margin: 0px 0px 15px">这样的唯一ID就可以用来表示你系统中使用的例如物品唯一ID，坐骑唯一ID等等数据，方便记录和追踪。</p>
<p style="margin: 0px 0px 15px">转载请注明：<a style="color: rgb(66,139,202); text-decoration: underline" title="" href="http://www.cppfans.org/" data-original-title="">C++爱好者博客</a><span class="Apple-converted-space">&nbsp;</span>&#187;<span class="Apple-converted-space">&nbsp;</span><a style="color: rgb(66,139,202); text-decoration: underline" title="" href="http://www.cppfans.org/1623.html" data-original-title="">网游服务器中的GUID(唯一标识码)实现-基于snowflake算法</a></p></article></div><img src ="http://www.cppblog.com/tx7do/aggbug/207138.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2014-05-29 01:33 <a href="http://www.cppblog.com/tx7do/archive/2014/05/29/207138.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>求最大公约数的3个实现</title><link>http://www.cppblog.com/tx7do/archive/2014/05/27/207113.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Tue, 27 May 2014 02:28:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2014/05/27/207113.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/207113.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2014/05/27/207113.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/207113.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/207113.html</trackback:ping><description><![CDATA[<div>实现代码：
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img id="Codehighlighter1_0_28_Open_Image" onclick="this.style.display='none'; Codehighlighter1_0_28_Open_Text.style.display='none'; Codehighlighter1_0_28_Closed_Image.style.display='inline'; Codehighlighter1_0_28_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_0_28_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_0_28_Closed_Text.style.display='none'; Codehighlighter1_0_28_Open_Image.style.display='inline'; Codehighlighter1_0_28_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_0_28_Closed_Text">/**/</span><span id="Codehighlighter1_0_28_Open_Text"><span style="color: #808080">///</span><span style="color: #008000">&nbsp;求最大公约数(欧几里德算法/辗转相除法)(递归)</span><span style="color: #808080"></span></span><br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" /><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;gcd1(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;m,&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;n)<br /><img id="Codehighlighter1_52_104_Open_Image" onclick="this.style.display='none'; Codehighlighter1_52_104_Open_Text.style.display='none'; Codehighlighter1_52_104_Closed_Image.style.display='inline'; Codehighlighter1_52_104_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_52_104_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_52_104_Closed_Text.style.display='none'; Codehighlighter1_52_104_Open_Image.style.display='inline'; Codehighlighter1_52_104_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_52_104_Closed_Text"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_52_104_Open_Text"><span style="color: #000000">{<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(n&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">)&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;m;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;gcd1(n,&nbsp;m</span><span style="color: #000000">%</span><span style="color: #000000">n);<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif"  alt="" />}</span></span><span style="color: #000000"><br /><img id="Codehighlighter1_106_134_Open_Image" onclick="this.style.display='none'; Codehighlighter1_106_134_Open_Text.style.display='none'; Codehighlighter1_106_134_Closed_Image.style.display='inline'; Codehighlighter1_106_134_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_106_134_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_106_134_Closed_Text.style.display='none'; Codehighlighter1_106_134_Open_Image.style.display='inline'; Codehighlighter1_106_134_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_106_134_Closed_Text">/**/</span><span id="Codehighlighter1_106_134_Open_Text"><span style="color: #808080">///</span><span style="color: #008000">&nbsp;求最大公约数(欧几里德算法/辗转相除法)(迭代)</span><span style="color: #808080"></span></span><br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" /><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;gcd2(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;m,&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;n)<br /><img id="Codehighlighter1_158_236_Open_Image" onclick="this.style.display='none'; Codehighlighter1_158_236_Open_Text.style.display='none'; Codehighlighter1_158_236_Closed_Image.style.display='inline'; Codehighlighter1_158_236_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_158_236_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_158_236_Closed_Text.style.display='none'; Codehighlighter1_158_236_Open_Image.style.display='inline'; Codehighlighter1_158_236_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_158_236_Closed_Text"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_158_236_Open_Text"><span style="color: #000000">{<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;r&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">&nbsp;(n&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">)<br /><img id="Codehighlighter1_189_223_Open_Image" onclick="this.style.display='none'; Codehighlighter1_189_223_Open_Text.style.display='none'; Codehighlighter1_189_223_Closed_Image.style.display='inline'; Codehighlighter1_189_223_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_189_223_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_189_223_Closed_Text.style.display='none'; Codehighlighter1_189_223_Open_Image.style.display='inline'; Codehighlighter1_189_223_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_189_223_Closed_Text"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_189_223_Open_Text"><span style="color: #000000">{<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;n;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;m&nbsp;</span><span style="color: #000000">%</span><span style="color: #000000">&nbsp;n;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;r;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;m;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif"  alt="" />}</span></span><span style="color: #000000"><br /><img id="Codehighlighter1_238_255_Open_Image" onclick="this.style.display='none'; Codehighlighter1_238_255_Open_Text.style.display='none'; Codehighlighter1_238_255_Closed_Image.style.display='inline'; Codehighlighter1_238_255_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_238_255_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_238_255_Closed_Text.style.display='none'; Codehighlighter1_238_255_Open_Image.style.display='inline'; Codehighlighter1_238_255_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_238_255_Closed_Text">/**/</span><span id="Codehighlighter1_238_255_Open_Text"><span style="color: #808080">///</span><span style="color: #008000">&nbsp;求最大公约数(更相减损法)</span><span style="color: #808080"></span></span><br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" /><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;gcd3(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;m,&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;n)<br /><img id="Codehighlighter1_279_350_Open_Image" onclick="this.style.display='none'; Codehighlighter1_279_350_Open_Text.style.display='none'; Codehighlighter1_279_350_Closed_Image.style.display='inline'; Codehighlighter1_279_350_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_279_350_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_279_350_Closed_Text.style.display='none'; Codehighlighter1_279_350_Open_Image.style.display='inline'; Codehighlighter1_279_350_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_279_350_Closed_Text"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_279_350_Open_Text"><span style="color: #000000">{<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">&nbsp;(m&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;n)<br /><img id="Codehighlighter1_298_337_Open_Image" onclick="this.style.display='none'; Codehighlighter1_298_337_Open_Text.style.display='none'; Codehighlighter1_298_337_Closed_Image.style.display='inline'; Codehighlighter1_298_337_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_298_337_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_298_337_Closed_Text.style.display='none'; Codehighlighter1_298_337_Open_Image.style.display='inline'; Codehighlighter1_298_337_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_298_337_Closed_Text"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_298_337_Open_Text"><span style="color: #000000">{<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(m&nbsp;</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;n)&nbsp;m&nbsp;</span><span style="color: #000000">-=</span><span style="color: #000000">&nbsp;n;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;n&nbsp;</span><span style="color: #000000">-=</span><span style="color: #000000">&nbsp;m;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;m;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif"  alt="" />}</span></span></div><br />测试代码：<br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"  alt="" /><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;_tmain(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;argc,&nbsp;_TCHAR</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;argv[])<br /><img id="Codehighlighter1_37_201_Open_Image" onclick="this.style.display='none'; Codehighlighter1_37_201_Open_Text.style.display='none'; Codehighlighter1_37_201_Closed_Image.style.display='inline'; Codehighlighter1_37_201_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_37_201_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_37_201_Closed_Text.style.display='none'; Codehighlighter1_37_201_Open_Image.style.display='inline'; Codehighlighter1_37_201_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_37_201_Closed_Text"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_37_201_Open_Text"><span style="color: #000000">{<br /><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;nGcd&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;gcd1(</span><span style="color: #000000">16</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">40</span><span style="color: #000000">);<br /><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;assert(nGcd&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">8</span><span style="color: #000000">);<br /><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"  alt="" /><br /><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;nGcd&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;gcd2(</span><span style="color: #000000">16</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">40</span><span style="color: #000000">);<br /><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;assert(nGcd&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">8</span><span style="color: #000000">);<br /><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"  alt="" /><br /><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;nGcd&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;gcd3(</span><span style="color: #000000">16</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">40</span><span style="color: #000000">);<br /><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;assert(nGcd&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">8</span><span style="color: #000000">);<br /><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"  alt="" /><br /><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;system(</span><span style="color: #000000">"</span><span style="color: #000000">pause</span><span style="color: #000000">"</span><span style="color: #000000">);<br /><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br /><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif"  alt="" />}</span></span></div></div><img src ="http://www.cppblog.com/tx7do/aggbug/207113.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2014-05-27 10:28 <a href="http://www.cppblog.com/tx7do/archive/2014/05/27/207113.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>字节对齐（强制对齐以及自然对齐）</title><link>http://www.cppblog.com/tx7do/archive/2014/04/17/206618.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Thu, 17 Apr 2014 07:43:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2014/04/17/206618.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/206618.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2014/04/17/206618.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/206618.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/206618.html</trackback:ping><description><![CDATA[<div>转载自：<a href="http://www.cnblogs.com/alfredzzj/archive/2012/06/17/2552431.html">http://www.cnblogs.com/alfredzzj/archive/2012/06/17/2552431.html</a><br /><br />
<div style="margin-bottom: 20px" id="cnblogs_post_body">
<p style="text-indent: 0px; margin: 10px auto">struct {}node;</p>
<p style="text-indent: 0px; margin: 10px auto">32为的x86，window下VC下sizeof(node)的值为1，而linux的gcc下值为0；</p>
<hr />

<p style="text-indent: 0px; margin: 10px auto">一、WINDOWS下（VC--其实GCC和其原理基本一样，象这种问题，一般要查具体的编译器设置）字节对齐的规则：</p>
<p style="text-indent: 0px; margin: 10px auto">1、一般设置的对齐方式为1，2，4字节对齐方式，VC一般默认为4字节(最大为8字节)。结构的首地址必须是结构内最宽类型的整数倍地址；另外，结构体的每一个成员起始地址必须是自身类型大小的整数倍(需要特别注意的是windows下是这样的，但在linux的gcc编译器下最高为4字节对齐），否则在前一类型后补0；这里特别提到的是数组一定要注意，而且在一些编程的技巧中，我们可以使用数组强制字节达到对齐的目的。这在网络编程中是很常见的。</p>
<p style="text-indent: 0px; margin: 10px auto">举例：比如CHAR型占用空间为1字节，则其起始位置必须可被1整除。INT为4字节，其起始位置必须被4带队，依次类推。（我们假定类或结构体的起始位置为0位置，其实编译器是在开辟空间时，会寻找起始位置可被结构内最宽类型整除的地址做为开始地址，因此我们可以假定其为0值，因为这0值可以被任意的类型整除。）</p>
<p style="text-indent: 0px; margin: 10px auto">2、结构体的整体大小必须可被对齐值整除，默认4（默认，且结构中的类型大小都小于默认的4）。</p>
<p style="text-indent: 0px; margin: 10px auto">3、结构体的整体大小必须可被本结构内的最宽类型整除。（其实和上一条是一样的，但这里独立出来，起注意作用。比如结构体里的有DOUBLE，那么结构的大小最后必须可被8整除）</p>
<p style="text-indent: 0px; margin: 10px auto"><strong>注意：GCC不是这样，就是最高只能被4整除，它是个死的。</strong></p>
<p style="text-indent: 0px; margin: 10px auto">否则（2、3条），编译器会在结构的最后添充一定的特定字符来补齐。</p>
<p style="text-indent: 0px; margin: 10px auto">struct T<span class="Apple-converted-space">&nbsp;</span><br />{<span class="Apple-converted-space">&nbsp;</span><br />char ch;<span class="Apple-converted-space">&nbsp;</span><br />double d ;<span class="Apple-converted-space">&nbsp;</span><br />};</p>
<p style="text-indent: 0px; margin: 10px auto">在VC中是16个字节，GCC中为12个字节。</p>
<p style="text-indent: 0px; margin: 10px auto">4、对于结构体内嵌套结构体的形势，规定是必须按照基本数据类型来定义，而不能以嵌套结构大小来做为上三种使用的基准。</p>
<p style="text-indent: 0px; margin: 10px auto">二、举例：</p>
<p style="text-indent: 0px; margin: 10px auto">struct A<span class="Apple-converted-space">&nbsp;</span><br />{<span class="Apple-converted-space">&nbsp;</span><br />int a;<span class="Apple-converted-space">&nbsp;</span><br />char b;<span class="Apple-converted-space">&nbsp;</span><br />short c;<span class="Apple-converted-space">&nbsp;</span><br />};<span class="Apple-converted-space">&nbsp;</span><br />struct B<span class="Apple-converted-space">&nbsp;</span><br />{<span class="Apple-converted-space">&nbsp;</span><br />char b;<span class="Apple-converted-space">&nbsp;</span><br />int a;<span class="Apple-converted-space">&nbsp;</span><br />short c;<span class="Apple-converted-space">&nbsp;</span><br />};<span class="Apple-converted-space">&nbsp;</span><br />struct C<span class="Apple-converted-space">&nbsp;</span><br />{<span class="Apple-converted-space">&nbsp;</span><br />double t;<span class="Apple-converted-space">&nbsp;</span><br />char b;<span class="Apple-converted-space">&nbsp;</span><br />int a;<span class="Apple-converted-space">&nbsp;</span><br />short c;<span class="Apple-converted-space">&nbsp;</span><br />};<span class="Apple-converted-space">&nbsp;</span><br />struct D<span class="Apple-converted-space">&nbsp;</span><br />{<span class="Apple-converted-space">&nbsp;</span><br />char b;<span class="Apple-converted-space">&nbsp;</span><br />double t;<span class="Apple-converted-space">&nbsp;</span><br />int a;<span class="Apple-converted-space">&nbsp;</span><br />short c;<span class="Apple-converted-space">&nbsp;</span><br />};</p>
<p style="text-indent: 0px; margin: 10px auto">在VC中，SIZEOF这四个结构体，分别为：8、12、24、24；</p>
<p style="text-indent: 0px; margin: 10px auto">我们先谈第一个，（<strong>说明一下，在考虑结构体大小时，我们基本可以忽略起始地址的问题，因为这个编译器会自动为我们做好，见上面的说明</strong>），结构体内首先是一个INT的4字节，起始地址假定为0，整除4，其小于等于默认的4字节对齐且0为4（INT的占用空间）的整数倍，所以，其占四个字节；其后为起始地址为5，空间为1个字节的CHAR，小于4且5为1（CHAR占用空间）的整数倍，故占用1个字节，然后是一个起始地址为5占2个字节的SHORT，其小于4，但5不为2位数，故补齐一个字节，从第6个字节开始，占2字节空间。所以共占用4+1+1（补）+2=8；8/4=2；整除，故占用<strong>8字节</strong>空间。</p>
<p style="text-indent: 0px; margin: 10px auto">再谈第2个，CHAR不用解释，占有一个字节空间，且可以被0地址整除。而INT则占4字节空间，所以其必须在CHAR后补齐3字节，到第四个字节，才是INT的真正地址。SHORT也不用说，所以共占有：1+3（补）+4+2=10个字节，但10不能整除4，所以要在结构体最后补齐2字节。故实际占有10+2= 12个字节。</p>
<p style="text-indent: 0px; margin: 10px auto">谈第三个，C结构体只是在B结构体前加了一个DOUBLE，其它都一样，按说应该是20个字节啊，但注意我们上面规则的第3条。必须是最宽类型的整数倍，一定要分清，所以得补齐到24，D结构体类似，不再讲。</p>
<p style="text-indent: 0px; margin: 10px auto">三、结构体的中含有位域</p>
<p style="text-indent: 0px; margin: 10px auto">这个东西用得比较少，但还是总结一下：</p>
<p style="text-indent: 0px; margin: 10px auto">如果<strong>结构</strong>体中含有位域(bit-field)，那么VC中准则又要有所更改：<span class="Apple-converted-space">&nbsp;</span><br />1) 如果相邻位域字段的类型相同，且其位宽之和小于类型的sizeof大小，则后面的字段将紧邻前一个字段存储，直到不能容纳为止；<span class="Apple-converted-space">&nbsp;</span><br />2) 如果相邻位域字段的类型相同，但其位宽之和大于类型的sizeof大小，则后面的字段将从新的存储单元开始，其偏移量为其类型大小的整数倍；<span class="Apple-converted-space">&nbsp;</span><br />3) 如果相邻的位域字段的类型不同，则各编译器的具体实现有差异，VC6采取不压缩方式（不同位域字段存放在不同的位域类型字节中），Dev-C++和GCC都采取压缩方式；<span class="Apple-converted-space">&nbsp;</span><br /><em>备注：当两字段类型不一样的时候，对于不压缩方式，例如：</em></p>
<p style="text-indent: 0px; margin: 10px auto"><em>struct N<span class="Apple-converted-space">&nbsp;</span><br />{<span class="Apple-converted-space">&nbsp;</span><br />char c:2;<span class="Apple-converted-space">&nbsp;</span><br />int i:4;<span class="Apple-converted-space">&nbsp;</span><br />};</em></p>
<p style="text-indent: 0px; margin: 10px auto"><em>依然要满足不含位域<strong>结构</strong>体内存<strong>对齐</strong>准则第2条，i成员相对于<strong>结构</strong>体首地址的偏移应该是4的整数倍，所以c成员后要填充3个字节，然后再开辟4个字节的空间作为int型，其中4位用来存放i，所以上面<strong>结构</strong>体在VC中所占空间为8个字节；而对于采用压缩方式的编译器来说，遵循不含位域<strong>结构</strong>体内存<strong>对齐</strong>准则第2条，不同的是，如果填充的3个字节能容纳后面成员的位，则压缩到填充字节中，不能容纳，则要单独开辟空间，所以上面<strong>结构</strong>体N在GCC或者Dev-C++中所占空间应该是4个字节。</em></p>
<p style="text-indent: 0px; margin: 10px auto">4) 如果位域字段之间穿插着非位域字段，则不进行压缩；<span class="Apple-converted-space">&nbsp;</span><br /><em>备注：<span class="Apple-converted-space">&nbsp;</span><br /><strong>结构</strong>体</em></p>
<p style="text-indent: 0px; margin: 10px auto"><em>typedef struct<span class="Apple-converted-space">&nbsp;</span><br />{<span class="Apple-converted-space">&nbsp;</span><br />char c:2;<span class="Apple-converted-space">&nbsp;</span><br />double i;<span class="Apple-converted-space">&nbsp;</span><br />int c2:4;<span class="Apple-converted-space">&nbsp;</span><br />}N3;</em></p>
<p style="text-indent: 0px; margin: 10px auto"><em>在GCC下占据的空间为16字节，在VC下占据的空间应该是24个字节。</em></p>
<p style="text-indent: 0px; margin: 10px auto"><em></em></p>
<p style="text-indent: 0px; margin: 10px auto">四、字节对齐的控制方法</p>
<p style="text-indent: 0px; margin: 10px auto">主要是使用：</p>
<p style="text-indent: 0px; margin: 10px auto">#pragma pack (2) /*指定按2字节对齐*/<span class="Apple-converted-space">&nbsp;</span><br />struct C<span class="Apple-converted-space">&nbsp;</span><br />{<span class="Apple-converted-space">&nbsp;</span><br />char b;<span class="Apple-converted-space">&nbsp;</span><br />int a;<span class="Apple-converted-space">&nbsp;</span><br />short c;<span class="Apple-converted-space">&nbsp;</span><br />};<span class="Apple-converted-space">&nbsp;</span><br />#pragma pack () /*取消指定对齐，恢复缺省对齐*/</p>
<p style="text-indent: 0px; margin: 10px auto">大家如果有兴趣，可以自己上机调一下各种对齐方式下的占用空间大小，这里就不再举例。</p>
<p style="text-indent: 0px; margin: 10px auto">#pragma pack(push) //保存对齐状态<span class="Apple-converted-space">&nbsp;</span><br /><strong>#pragma pack(4)//</strong>设定为4字节对齐<span class="Apple-converted-space">&nbsp;</span><br />struct test<span class="Apple-converted-space">&nbsp;</span><br />{<span class="Apple-converted-space">&nbsp;</span><br />char m1;<span class="Apple-converted-space">&nbsp;</span><br />double m4;<span class="Apple-converted-space">&nbsp;</span><br />int m3;<span class="Apple-converted-space">&nbsp;</span><br />};<span class="Apple-converted-space">&nbsp;</span><br /><strong>#pragma pack(pop)//</strong>恢复对齐状态</p>
<p style="text-indent: 0px; margin: 10px auto">这里需要<strong>注意的是，如果对齐的字节非为1、2、4、8等可整除位数，则自动默认回默认的对齐字节数</strong>，这个我没有测试，大家可以试一下，应该没什么问题。</p>
<p style="text-indent: 0px; margin: 10px auto">五、多编译器的使用：（<strong>其下为转载</strong>）</p>
<p style="text-indent: 0px; margin: 10px auto">为了防止不同编译器对齐不一样，建议在代码里面指定对齐参数</p>
<p style="text-indent: 0px; margin: 10px auto">可能重要的一点是关于紧缩结构的。紧缩结构的用途 其实最常用的结构对齐选项就是：默认对齐和紧缩。在两个程序，或者两个平台之间传递数据时，我们通常会将数据结构设置为紧缩的。这样不仅可以减小通信量，还可以避免对齐带来的麻烦。假设甲乙双方进行跨平台通信，甲方使用了&#8220;/Zp2&#8221;这么奇怪的对齐选项，而乙方的编译器不支持这种对齐方式，那么乙方就可以理解什么叫欲哭无泪了。 当我们需要一个字节一个字节访问结构数据时，我们通常都会希望结构是紧缩的，这样就不必考虑哪个字节是填充字节了。我们把数据保存到非易失设备时，通常也会采用紧缩结构，既减小存储量，也方便其它程序读出。各编译器都支持结构的紧缩，即连续排列结构的各成员变量，各成员变量之间没有任何填充字节。这时，结构的大小等于各成员变量大小的和。紧缩结构的变量可以放在1n边界，即任意地址边界。在GNU gcc:</p>
<p style="text-indent: 0px; margin: 10px auto">typedef struct St2Tag</p>
<p style="text-indent: 0px; margin: 10px auto">{</p>
<p style="text-indent: 0px; margin: 10px auto">St1 st1;</p>
<p style="text-indent: 0px; margin: 10px auto">char ch2;</p>
<p style="text-indent: 0px; margin: 10px auto">}</p>
<p style="text-indent: 0px; margin: 10px auto">__attribute__ ((packed)) St2;</p>
<p style="text-indent: 0px; margin: 10px auto">在ARMCC：</p>
<p style="text-indent: 0px; margin: 10px auto">typedef __packed struct St2Tag</p>
<p style="text-indent: 0px; margin: 10px auto">{</p>
<p style="text-indent: 0px; margin: 10px auto">St1 st1;</p>
<p style="text-indent: 0px; margin: 10px auto">char ch2;</p>
<p style="text-indent: 0px; margin: 10px auto">} St2;</p>
<p style="text-indent: 0px; margin: 10px auto">在VC：</p>
<p style="text-indent: 0px; margin: 10px auto">#pragma pack(1)</p>
<p style="text-indent: 0px; margin: 10px auto">typedef struct St2Tag</p>
<p style="text-indent: 0px; margin: 10px auto">{</p>
<p style="text-indent: 0px; margin: 10px auto">St1 st1;</p>
<p style="text-indent: 0px; margin: 10px auto">char ch2;</p>
<p style="text-indent: 0px; margin: 10px auto">} St2;</p>
<p style="text-indent: 0px; margin: 10px auto">#pragma pack()</p>
<p style="text-indent: 0px; margin: 10px auto">针对不同的编译器：</p>
<p style="text-indent: 0px; margin: 10px auto">#ifdef __GNUC__</p>
<p style="text-indent: 0px; margin: 10px auto">#define GNUC_PACKED __attribute__ ((packed))</p>
<p style="text-indent: 0px; margin: 10px auto">#else</p>
<p style="text-indent: 0px; margin: 10px auto">#define GNUC_PACKED</p>
<p style="text-indent: 0px; margin: 10px auto">#endif</p>
<p style="text-indent: 0px; margin: 10px auto">#ifdef __arm</p>
<p style="text-indent: 0px; margin: 10px auto">#define ARM_PACKED __packed</p>
<p style="text-indent: 0px; margin: 10px auto">#else</p>
<p style="text-indent: 0px; margin: 10px auto">#define ARM_PACKED</p>
<p style="text-indent: 0px; margin: 10px auto">#endif</p>
<p style="text-indent: 0px; margin: 10px auto">#ifdef WIN32</p>
<p style="text-indent: 0px; margin: 10px auto">#pragma pack(1)</p>
<p style="text-indent: 0px; margin: 10px auto">#endif</p>
<p style="text-indent: 0px; margin: 10px auto">typedef ARM_PACKED struct St2Tag</p>
<p style="text-indent: 0px; margin: 10px auto">{</p>
<p style="text-indent: 0px; margin: 10px auto">St1 st1;</p>
<p style="text-indent: 0px; margin: 10px auto">char ch2;</p>
<p style="text-indent: 0px; margin: 10px auto">}</p>
<p style="text-indent: 0px; margin: 10px auto">GNUC_PACKED St2;</p>
<p style="text-indent: 0px; margin: 10px auto">#ifdef WIN32</p>
<p style="text-indent: 0px; margin: 10px auto">#pragma pack()</p>
<p style="text-indent: 0px; margin: 10px auto">#endif</p>
<p style="text-indent: 0px; margin: 10px auto">最后记录一个小细节。gcc编译器和VC编译器都支持在紧缩结构中包含非紧缩结构，例如前面例子中的St2可以包含非紧缩的St1。但对于ARM编译器而言，紧缩结构包含的其它结构必须是紧缩的。如果紧缩的St2包含了非紧缩的St1，编译时就会报错：</p>
<p style="text-indent: 0px; margin: 10px auto">&nbsp;</p>
<p style="text-indent: 0px; margin: 10px auto">&nbsp;</p>
<p style="text-indent: 0px; margin: 10px auto">&nbsp;</p>
<p style="text-indent: 0px; margin: 10px auto">&nbsp;</p>
<h5 style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font-size: 0.9em; padding-top: 0px">C语言的字节对齐及#pragma pack的使用</h5>
<p style="text-indent: 0px; margin: 10px auto">2010-04-16 09:44:33| 分类：<span class="Apple-converted-space">&nbsp;</span><a style="color: rgb(7,93,179); text-decoration: underline" href="http://alfalfa.1984.blog.163.com/blog/#m=0&amp;t=1&amp;c=fks_087067080085089070086087094095085086083070084080083064">vc/c/c++</a><span class="Apple-converted-space">&nbsp;</span>| 标签： |字号大中小<span class="Apple-converted-space">&nbsp;</span><a>订阅</a></p>
<p style="text-indent: 0px; margin: 10px auto">C编译器的缺省字节对齐方式（自然对界）</p>
<p style="text-indent: 0px; margin: 10px auto"><strong>在缺省情况下，C编译器为每一个变量或是数据单元按其自然对界条件分配空间。</strong></p>
<p style="text-indent: 0px; margin: 10px auto"><strong>在结构中，编译器为结构的每个成员按其自然对界（alignment）条件分配空间。各个成员按照它们被声明的顺序在内存中顺序存储（成员之间可能有插入的空字节），第一个成员的地址和整个结构的地址相同。</strong></p>
<p style="text-indent: 0px; margin: 10px auto"><strong></strong></p>
<p style="text-indent: 0px; margin: 10px auto"><strong>C编译器缺省的结构成员自然对界条件为&#8220;N字节对齐&#8221;，N即该成员数据类型的长度。</strong>如int型成员的自然对界条件为4字节对齐，而double类型的结构成员的自然对界条件为8字节对齐。若该成员的起始偏移不位于该成员的&#8220;默认自然对界条件&#8221;上，则在前一个节面后面添加适当个数的空字节。</p>
<p style="text-indent: 0px; margin: 10px auto"><strong>C编译器缺省的结构整体的自然对界条件为：该结构所有成员中要求的最大自然对界条件。</strong>若结构体各成员长度之和不为&#8220;结构整体自然对界条件的整数倍，则在最后一个成员后填充空字节。</p>
<p style="text-indent: 0px; margin: 10px auto">例子1（分析结构各成员的默认字节对界条界条件和结构整体的默认字节对界条件）:</p><pre style="margin-top: 0px; word-wrap: break-word; white-space: pre-wrap; margin-bottom: 0px"><p style="text-indent: 0px; margin: 10px auto">struct Test<br />{ <br />char x1; // 成员x1为char型(其起始地址必须1字节对界)，其偏移地址为0 <br /><br />char x2; // 成员x2为char型(其起始地址必须1字节对界，其偏移地址为1 <br /><br />float x3; // 成员x3为float型(其起始地址必须4字节对界)，编译器在x2和x3之间填充了两个空字节，其偏移地址为4 <br /><br />char x4; // 成员x4为char型(其起始地址必须1字节对界)，其偏移地址为8 <br />}; <br /></p></pre>
<p style="text-indent: 0px; margin: 10px auto">因为Test结构体中，最大的成员为flaot x3，因些此结构体的自然对界条件为4字节对齐。则结构体长度就为12字节，内存布局为1100 1111 1000。</p>
<p style="text-indent: 0px; margin: 10px auto">例子2：</p><pre style="margin-top: 0px; word-wrap: break-word; white-space: pre-wrap; margin-bottom: 0px"><p style="text-indent: 0px; margin: 10px auto">#include &lt;stdio.h&gt;<br />//#pragma pack(2)<br />typedef struct<br />{<br />  int aa1; //4个字节对齐 1111<br />  char bb1;//1个字节对齐 1<br />  short cc1;//2个字节对齐 011<br />  char dd1; //1个字节对齐 1<br />  } testlength1;<br />int length1 = sizeof(testlength1); //4个字节对齐，占用字节1111 1011 1000,length = 12<br /><br />typedef struct<br />{<br />  char bb2;//1个字节对齐 1<br />  int aa2; //4个字节对齐 01111<br />  short cc2;//2个字节对齐 11<br />  char dd2; //1个字节对齐 1<br />  } testlength2;<br />int length2 = sizeof(testlength2); //4个字节对齐，占用字节1011  1111 1000,length = 12<br /><br /><br />typedef struct<br />{<br />  char bb3; //1个字节对齐 1<br />  char dd3; //1个字节对齐 1<br />  int aa3; //4个字节对齐 001111<br />  short cc23//2个字节对齐 11<br /><br />  } testlength3;<br />int length3 = sizeof(testlength3); //4个字节对齐，占用字节1100 1111 1100,length = 12<br /><br /><br />typedef struct<br />{<br />  char bb4; //1个字节对齐 1<br />  char dd4; //1个字节对齐 1<br />  short cc4;//2个字节对齐 11<br />  int aa4; //4个字节对齐 1111<br />  } testlength4;<br />int length4 = sizeof(testlength4); //4个字节对齐，占用字节1111 1111,length = 8<br /><br /><br />int main(void)<br />{<br />  printf("length1 = %d.\n",length1);<br />  printf("length2 = %d.\n",length2);<br />  printf("length3 = %d.\n",length3);<br />  printf("length4 = %d.\n",length4);<br />  return 0;<br />}<br /></p></pre>
<p style="text-indent: 0px; margin: 10px auto"><strong>改变缺省的对界条件(指定对界)<span class="Apple-converted-space">&nbsp;</span><br />&#183; 使用伪指令#pragma pack (n)，C编译器将按照n个字节对齐。<span class="Apple-converted-space">&nbsp;</span><br />&#183; 使用伪指令#pragma pack ()，取消自定义字节对齐方式。</strong></p>
<p style="text-indent: 0px; margin: 10px auto">这时，对齐规则为：</p>
<p style="text-indent: 0px; margin: 10px auto">1<strong>、数据成员对齐规则：结构(struct)(或联合(union))的数据成员，第一个数据成员放在offset为0的地方，以后每个数据成员的对齐按照#pragma pack指定的数值和这个数据成员自身长度中，比较小的那个进行。</strong></p>
<p style="text-indent: 0px; margin: 10px auto"><strong>2、结构(或联合)的整体对齐规则：在数据成员完成各自对齐之后，结构(或联合)本身也要进行对齐，对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中，比较小的那个进行。</strong></p>
<p style="text-indent: 0px; margin: 10px auto"><strong>结合1、2推断：当#pragma pack的n值等于或超过所有数据成员长度的时候，这个n值的大小将不产生任何效果。</strong></p>
<p style="text-indent: 0px; margin: 10px auto"><strong></strong></p>
<p style="text-indent: 0px; margin: 10px auto">因此，当使用伪指令#pragma pack (2)时，Test结构体的大小为8，内存布局为11 11 11 10。</p>
<p style="text-indent: 0px; margin: 10px auto"><strong>需要注意一点，当结构体中包含一个子结构体时，子结构中的成员按照#pragma pack指定的数值和子结构最大数据成员长度中，比较小的那个进行进行对齐。</strong>例子如下：</p>
<p style="text-indent: 0px; margin: 10px auto">#pragma pack(8)<span class="Apple-converted-space">&nbsp;</span><br />struct s1{<span class="Apple-converted-space">&nbsp;</span><br />short a;<span class="Apple-converted-space">&nbsp;</span><br />long b;<span class="Apple-converted-space">&nbsp;</span><br />};</p>
<p style="text-indent: 0px; margin: 10px auto">struct s2{<span class="Apple-converted-space">&nbsp;</span><br />char c;<span class="Apple-converted-space">&nbsp;</span><br />s1 d;<span class="Apple-converted-space">&nbsp;</span><br />long long e;<span class="Apple-converted-space">&nbsp;</span><br />};<span class="Apple-converted-space">&nbsp;</span><br />#pragma pack()</p>
<p style="text-indent: 0px; margin: 10px auto">sizeof(s2)的结果为24。S1的内存布局为1100 1111，S2的内存布局为1000 1100 1111 0000 1111 1111。</p>
<p style="text-indent: 0px; margin: 10px auto">例子：</p><pre style="margin-top: 0px; word-wrap: break-word; white-space: pre-wrap; margin-bottom: 0px"><p style="text-indent: 0px; margin: 10px auto">#include &lt;stdio.h&gt;<br />#pragma pack(2)<br />typedef struct<br />{<br />  int aa1; //2个字节对齐 1111<br />  char bb1;//1个字节对齐 1<br />  short cc1;//2个字节对齐 011<br />  char dd1; //1个字节对齐 1<br />  } testlength1;<br />int length1 = sizeof(testlength1); //2个字节对齐，占用字节11 11 10 11 10,length = 10<br /><br />typedef struct<br />{<br />  char bb2;//1个字节对齐 1<br />  int aa2; //2个字节对齐 01111<br />  short cc2;//2个字节对齐 11<br />  char dd2; //1个字节对齐 1<br />  } testlength2;<br />int length2 = sizeof(testlength2); //2个字节对齐，占用字节10 11 11 11 10,length = 10<br /><br /><br />typedef struct<br />{<br />  char bb3; //1个字节对齐 1<br />  char dd3; //1个字节对齐 1<br />  int aa3; //2个字节对齐 11 11<br />  short cc23//2个字节对齐 11<br /><br />  } testlength3;<br />int length3 = sizeof(testlength3); //2个字节对齐，占用字节11 11 11 11,length = 8<br /><br /><br />typedef struct<br />{<br />  char bb4; //1个字节对齐 1<br />  char dd4; //1个字节对齐 1<br />  short cc4;//2个字节对齐 11<br />  int aa4; //2个字节对齐 11 11<br />  } testlength4;<br />int length4 = sizeof(testlength4); //2个字节对齐，占用字节11 11 11 11,length = 8<br /><br /><br />int main(void)<br />{<br />  printf("length1 = %d.\n",length1);<br />  printf("length2 = %d.\n",length2);<br />  printf("length3 = %d.\n",length3);<br />  printf("length4 = %d.\n",length4);<br />  return 0;<br />}<br /></p></pre>
<p style="text-indent: 0px; margin: 10px auto">另外，还有如下的一种方式：</p>
<p style="text-indent: 0px; margin: 10px auto">&#183; __attribute((aligned (n)))，让所作用的结构成员对齐在n字节自然边界上。如果结构中有成员的长度大于n，则按照最大成员的长度来对齐。</p>
<p style="text-indent: 0px; margin: 10px auto">&#183; __attribute__ ((packed))，取消结构在编译过程中的优化对齐，按照实际占用字节数进行对齐。</p>
<p style="text-indent: 0px; margin: 10px auto">以上的n = 1, 2, 4, 8, 16... 第一种方式较为常见。</p></div>
<div id="MySignature"></div>
<div style="clear: both" class="clear"></div>
<div style="margin-top: 20px" id="blog_post_info_block">
<div id="blog_post_info">
<div style="text-transform: none; text-indent: 0px; font: 13px/20px Verdana, Geneva, Arial, Helvetica, sans-serif; white-space: normal; margin-bottom: 10px; letter-spacing: normal; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-stroke-width: 0px" id="BlogPostCategory"></div>
<div style="text-transform: none; margin-top: 0px !important; text-indent: 0px; font: 13px/20px Verdana, Geneva, Arial, Helvetica, sans-serif; white-space: normal; letter-spacing: normal; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-stroke-width: 0px" id="EntryTag"></div><br class="Apple-interchange-newline" /></div></div></div><img src ="http://www.cppblog.com/tx7do/aggbug/206618.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2014-04-17 15:43 <a href="http://www.cppblog.com/tx7do/archive/2014/04/17/206618.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用libcurl实现的上传器</title><link>http://www.cppblog.com/tx7do/archive/2014/04/01/206424.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Tue, 01 Apr 2014 15:23:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2014/04/01/206424.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/206424.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2014/04/01/206424.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/206424.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/206424.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 头文件Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->/**//***********************************************************************&nbsp;Copyright&nbsp;...&nbsp;&nbsp;<a href='http://www.cppblog.com/tx7do/archive/2014/04/01/206424.html'>阅读全文</a><img src ="http://www.cppblog.com/tx7do/aggbug/206424.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2014-04-01 23:23 <a href="http://www.cppblog.com/tx7do/archive/2014/04/01/206424.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>窗口大小控制MINMAXINFO</title><link>http://www.cppblog.com/tx7do/archive/2014/03/12/206136.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Tue, 11 Mar 2014 17:04:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2014/03/12/206136.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/206136.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2014/03/12/206136.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/206136.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/206136.html</trackback:ping><description><![CDATA[<div><strong style="color: red">转载自：</strong><a style="color: red" href="http://blog.csdn.net/sqcfj/article/details/7245568"><strong>http://blog.csdn.net/sqcfj/article/details/7245568</strong></a><br /><br />
<div style="text-align: left; text-transform: none; text-indent: 0px; margin: 20px 0px 0px; font: 14px/26px Arial; white-space: normal; letter-spacing: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px" id="article_content" class="article_content">
<p>为了控制窗口的大小，在窗口初始化时，需要用到MINMAXINFO结构体。</p>
<p><strong>结构体：</strong></p>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><img id="Codehighlighter1_15_122_Open_Image" onclick="this.style.display='none'; Codehighlighter1_15_122_Open_Text.style.display='none'; Codehighlighter1_15_122_Closed_Image.style.display='inline'; Codehighlighter1_15_122_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_15_122_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_15_122_Closed_Text.style.display='none'; Codehighlighter1_15_122_Open_Image.style.display='inline'; Codehighlighter1_15_122_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"><span style="color: #000000">typedef&nbsp;</span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_15_122_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_15_122_Open_Text"><span style="color: #000000">{<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;POINT&nbsp;ptReserved;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;POINT&nbsp;ptMaxSize;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;POINT&nbsp;ptMaxPosition;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;POINT&nbsp;ptMinTrackSize;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;POINT&nbsp;ptMaxTrackSize;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span><span style="color: #000000">&nbsp;MINMAXINFO;</span></div>
<p><strong><br />参数说明：<br /></strong>&nbsp;ptMaxSize：&nbsp;&nbsp;设置窗口最大化时的宽度、高度<br />&nbsp;ptMaxPosition：&nbsp;设置窗口最大化时x坐标、y坐标<br />&nbsp;ptMinTrackSize：&nbsp;设置窗口最小宽度、高度<br />&nbsp;ptMaxTrackSize：设置窗口最大宽度、高度<br /><br /></p>
<p><strong>实例：<br /></strong>1、在窗口类映射ON_WM_GETMINMAXINFO消息；<br />2、在该函数修改MINMAXINFO结构体数据：</p>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;CTestDlg::OnGetMinMaxInfo(MINMAXINFO&nbsp;FAR</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;lpMMI)&nbsp;<br /><img id="Codehighlighter1_55_445_Open_Image" onclick="this.style.display='none'; Codehighlighter1_55_445_Open_Text.style.display='none'; Codehighlighter1_55_445_Closed_Image.style.display='inline'; Codehighlighter1_55_445_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_55_445_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_55_445_Closed_Text.style.display='none'; Codehighlighter1_55_445_Open_Image.style.display='inline'; Codehighlighter1_55_445_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_55_445_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_55_445_Open_Text"><span style="color: #000000">{<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;lpMMI</span><span style="color: #000000">-&gt;</span><span style="color: #000000">ptMaxSize.x&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">800</span><span style="color: #000000">;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;设置窗口最大化时的宽度</span><span style="color: #008000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;lpMMI</span><span style="color: #000000">-&gt;</span><span style="color: #000000">ptMaxSize.y&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">600</span><span style="color: #000000">;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;设置窗口最大化时的高度</span><span style="color: #008000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;lpMMI</span><span style="color: #000000">-&gt;</span><span style="color: #000000">ptMaxPosition.x&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">100</span><span style="color: #000000">;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;设置窗口最大化时x坐标</span><span style="color: #008000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;lpMMI</span><span style="color: #000000">-&gt;</span><span style="color: #000000">ptMaxPosition.y&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">100</span><span style="color: #000000">;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;设置窗口最大化时y坐标</span><span style="color: #008000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;lpMMI</span><span style="color: #000000">-&gt;</span><span style="color: #000000">ptMinTrackSize.x&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">400</span><span style="color: #000000">;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;设置窗口最小宽度</span><span style="color: #008000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;lpMMI</span><span style="color: #000000">-&gt;</span><span style="color: #000000">ptMinTrackSize.y&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">400</span><span style="color: #000000">;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;设置窗口最小高度</span><span style="color: #008000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;lpMMI</span><span style="color: #000000">-&gt;</span><span style="color: #000000">ptMaxTrackSize.x&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">600</span><span style="color: #000000">;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;设置窗口最大宽度</span><span style="color: #008000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;lpMMI</span><span style="color: #000000">-&gt;</span><span style="color: #000000">ptMaxTrackSize.y&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">500</span><span style="color: #000000">;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;设置窗口最大高度</span><span style="color: #008000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;CDialog::OnGetMinMaxInfo(lpMMI);<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span></div>
<p>&nbsp;</p></div>
<div style="z-index: 999999; text-align: left; padding-bottom: 2px; text-transform: none; text-indent: 0px; zoom: 1; font: 12px Arial, Console, Verdana, 'Courier New'; white-space: normal; float: right; letter-spacing: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px" id="bdshare" class="bdshare_t bds_tools get-codes-bdshare"><br class="Apple-interchange-newline" /></div></div><img src ="http://www.cppblog.com/tx7do/aggbug/206136.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2014-03-12 01:04 <a href="http://www.cppblog.com/tx7do/archive/2014/03/12/206136.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>对Windows下的File Mapping一个简单的封装</title><link>http://www.cppblog.com/tx7do/archive/2014/02/25/205927.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Mon, 24 Feb 2014 16:29:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2014/02/25/205927.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/205927.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2014/02/25/205927.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/205927.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/205927.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 头文件：Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->#ifndef&nbsp;__SharedMemory_H__#define&nbsp;__SharedMemory_H__class&nbsp;SharedMemory{public:&nb...&nbsp;&nbsp;<a href='http://www.cppblog.com/tx7do/archive/2014/02/25/205927.html'>阅读全文</a><img src ="http://www.cppblog.com/tx7do/aggbug/205927.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2014-02-25 00:29 <a href="http://www.cppblog.com/tx7do/archive/2014/02/25/205927.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ 运算符优先级列表</title><link>http://www.cppblog.com/tx7do/archive/2014/01/18/205464.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Sat, 18 Jan 2014 13:46:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2014/01/18/205464.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/205464.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2014/01/18/205464.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/205464.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/205464.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 介绍&nbsp;&nbsp;&nbsp;&nbsp;运算符是告诉编译程序执行特定算术或逻辑操作的符号。C语言的运算范围很宽，把除了控制语句和输入输出以外的几乎所有的基本操作都作为运算符处理。主要分为三大类：算术运算符、 关系运算符与逻辑运算符。除此之外，还有一些用于完成特殊任务的运算符。运算符的优先级与结合性&nbsp;&nbsp;&nbsp;&nbsp;优先级：C语言中，运算...&nbsp;&nbsp;<a href='http://www.cppblog.com/tx7do/archive/2014/01/18/205464.html'>阅读全文</a><img src ="http://www.cppblog.com/tx7do/aggbug/205464.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2014-01-18 21:46 <a href="http://www.cppblog.com/tx7do/archive/2014/01/18/205464.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于Google的SparseHashMap</title><link>http://www.cppblog.com/tx7do/archive/2013/04/22/199641.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Mon, 22 Apr 2013 09:43:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2013/04/22/199641.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/199641.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2013/04/22/199641.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/199641.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/199641.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 官方网站:http://google-sparsehash.googlecode.com官方说,可以轻松的用dense_hash_map和sparse_hash_map替换掉hash_map或者unordered_map.dense系列适用于"小字典",sparse系列适用于"大字典".这货挺好使的,性能上也是不错的.但是呢,有两点比较伤脑筋,这和其他的hashmap不兼容,那就是要在dense要...&nbsp;&nbsp;<a href='http://www.cppblog.com/tx7do/archive/2013/04/22/199641.html'>阅读全文</a><img src ="http://www.cppblog.com/tx7do/aggbug/199641.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2013-04-22 17:43 <a href="http://www.cppblog.com/tx7do/archive/2013/04/22/199641.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>剖析 epoll ET/LT 触发方式的性能差异误解（定性分析）</title><link>http://www.cppblog.com/tx7do/archive/2013/04/20/199579.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Fri, 19 Apr 2013 16:59:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2013/04/20/199579.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/199579.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2013/04/20/199579.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/199579.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/199579.html</trackback:ping><description><![CDATA[<div><strong style="color: red">转载自:</strong><a style="color: red" href="http://blog.linezing.com/2011/01/%E5%89%96%E6%9E%90-epoll-etlt-%E8%A7%A6%E5%8F%91%E6%96%B9%E5%BC%8F%E7%9A%84%E6%80%A7%E8%83%BD%E5%B7%AE%E5%BC%82%E8%AF%AF%E8%A7%A3%EF%BC%88%E5%AE%9A%E6%80%A7%E5%88%86%E6%9E%90%EF%BC%89"><strong>http://blog.linezing.com/2011/01/%E5%89%96%E6%9E%90-epoll-etlt-%E8%A7%A6%E5%8F%91%E6%96%B9%E5%BC%8F%E7%9A%84%E6%80%A7%E8%83%BD%E5%B7%AE%E5%BC%82%E8%AF%AF%E8%A7%A3%EF%BC%88%E5%AE%9A%E6%80%A7%E5%88%86%E6%9E%90%EF%BC%89</strong></a><br /><br />
<div style="text-align: left; padding-bottom: 0px; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 0px; padding-left: 0px; letter-spacing: normal; padding-right: 0px; font: 12px 'Microsoft Yahei', Tahoma, Arial, Helvetica, sans-serif; white-space: normal; color: rgb(51,51,51); overflow: hidden; word-spacing: 0px; padding-top: 18px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" class="entry">
<p style="padding-bottom: 0px; line-height: 18px; margin: 0px 0px 18px; padding-left: 0px; padding-right: 0px; font-family: 微软雅黑; color: black; font-size: 16px; padding-top: 0px">平时大家使用 epoll 时都知道其事件触发模式有默认的 level-trigger 模式和通过 EPOLLET 启用的 edge-trigger 模式两种。从 epoll 发展历史来看，它刚诞生时只有 edge-trigger 模式，后来因容易产生 race-cond 且不易被开发者理解，又增加了 level-trigger 模式并作为默认处理方式。</p>
<p style="padding-bottom: 0px; line-height: 18px; margin: 0px 0px 18px; padding-left: 0px; padding-right: 0px; font-family: 微软雅黑; color: black; font-size: 16px; padding-top: 0px">二者的差异在于 level-trigger 模式下只要某个 fd 处于 readable/writable 状态，无论什么时候进行 epoll_wait 都会返回该 fd；而 edge-trigger 模式下只有某个 fd 从 unreadable 变为 readable 或从 unwritable 变为 writable 时，epoll_wait 才会返回该 fd。</p>
<p style="padding-bottom: 0px; line-height: 18px; margin: 0px 0px 18px; padding-left: 0px; padding-right: 0px; font-family: 微软雅黑; color: black; font-size: 16px; padding-top: 0px"><strong style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">通常的误区是：level-trigger 模式在 epoll 池中存在大量 fd 时效率要显著低于 edge-trigger 模式。</strong></p>
<p style="padding-bottom: 0px; line-height: 18px; margin: 0px 0px 18px; padding-left: 0px; padding-right: 0px; font-family: 微软雅黑; color: black; font-size: 16px; padding-top: 0px">但从 kernel 代码来看，edge-trigger/level-trigger 模式的处理逻辑几乎完全相同，差别仅在于 level-trigger 模式在 event 发生时不会将其从 ready list 中移除，略为增大了 event 处理过程中 kernel space 中记录数据的大小。</p>
<p style="padding-bottom: 0px; line-height: 18px; margin: 0px 0px 18px; padding-left: 0px; padding-right: 0px; font-family: 微软雅黑; color: black; font-size: 16px; padding-top: 0px">然而，edge-trigger 模式一定要配合 user app 中的 ready list 结构，以便收集已出现 event 的 fd，再通过 round-robin 方式挨个处理，以此避免通信数据量很大时出现忙于处理热点 fd 而导致非热点 fd 饿死的现象。统观 kernel 和 user space，由于 user app 中 ready list 的实现千奇百怪，不一定都经过仔细的推敲优化，因此 edge-trigger 的总内存开销往往还大于 level-trigger 的开销。</p>
<p style="padding-bottom: 0px; line-height: 18px; margin: 0px 0px 18px; padding-left: 0px; padding-right: 0px; font-family: 微软雅黑; color: black; font-size: 16px; padding-top: 0px">一般号称 edge-trigger 模式的优势在于能够减少 epoll 相关系统调用，这话不假，但 user app 里可不是只有 epoll 相关系统调用吧？为了绕过饿死问题，edge-trigger 模式的 user app 要自行进行 read/write 循环处理，这其中增加的系统调用和减少的 epoll 系统调用加起来，有谁能说一定就能明显地快起来呢？</p>
<p style="padding-bottom: 0px; line-height: 18px; margin: 0px 0px 18px; padding-left: 0px; padding-right: 0px; font-family: 微软雅黑; color: black; font-size: 16px; padding-top: 0px">实际上，epoll_wait 的效率是 O(ready fd num) 级别的，因此 edge-trigger 模式的真正优势在于减少了每次 epoll_wait 可能需要返回的 fd 数量，在并发 event 数量极多的情况下能加快 epoll_wait 的处理速度，但别忘了这只是针对 epoll 体系自己而言的提升，与此同时 user app 需要增加复杂的逻辑、花费更多的 cpu/mem 与其配合工作，总体性能收益究竟如何？只有实际测量才知道，无法一概而论。不过，为了降低处理逻辑复杂度，常用的事件处理库大部分都选择了 level-trigger 模式（如 libevent、boost::asio等）</p>
<p style="padding-bottom: 0px; line-height: 18px; margin: 0px 0px 18px; padding-left: 0px; padding-right: 0px; font-family: 微软雅黑; color: black; font-size: 16px; padding-top: 0px"><strong style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">结论：<br style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" />&#8226; epoll 的 edge-trigger 和 level-trigger 模式处理逻辑差异极小，性能测试结果表明常规应用场景 中二者性能差异可以忽略。<br style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" />&#8226; 使用 edge-trigger 的 user app 比使用 level-trigger 的逻辑复杂，出错概率更高。<br style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" />&#8226; edge-trigger 和 level-trigger 的性能差异主要在于 epoll_wait 系统调用的处理速度，是否是 user app 的性能瓶颈需要视应用场景而定，不可一概而论。</strong></p>
<p style="padding-bottom: 0px; line-height: 18px; margin: 0px 0px 18px; padding-left: 0px; padding-right: 0px; font-family: 微软雅黑; color: black; font-size: 14px; padding-top: 0px">欢迎就此话题进行深入调研、讨论！</p>
<p style="padding-bottom: 0px; line-height: 18px; margin: 0px 0px 18px; padding-left: 0px; padding-right: 0px; font-family: 微软雅黑; color: black; font-size: 12px; padding-top: 0px">参考资料：<br style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" />&#8226; linux kernel source：fs/eventpoll.c<br style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" />&#8226; &#8220;Comparing and Evaluating epoll, select, and poll Event<br style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" />Mechanisms&#8221;：http://bcr2.uwaterloo.ca/~brecht/papers/getpaper.php?file=ols-2004.pdf<br style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" />&#8226; &#8220;Edge-triggered interfaces are too difficult?&#8221;：http://lwn.net/Articles/25137/</p>
<p style="padding-bottom: 0px; line-height: 18px; margin: 0px 0px 18px; padding-left: 0px; padding-right: 0px; padding-top: 0px">By QingWu</p></div>
<p style="text-align: left; padding-bottom: 0px; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 0px 0px 18px; padding-left: 0px; letter-spacing: normal; padding-right: 0px; font: 12px/18px 'Microsoft Yahei', Tahoma, Arial, Helvetica, sans-serif; white-space: normal; color: rgb(153,153,153); overflow: hidden; word-spacing: 0px; padding-top: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" class="post-info-bottom"><br class="Apple-interchange-newline" /></p></div><img src ="http://www.cppblog.com/tx7do/aggbug/199579.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2013-04-20 00:59 <a href="http://www.cppblog.com/tx7do/archive/2013/04/20/199579.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用Libaad2来进行AAC解码</title><link>http://www.cppblog.com/tx7do/archive/2013/02/02/197682.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Sat, 02 Feb 2013 09:51:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2013/02/02/197682.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/197682.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2013/02/02/197682.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/197682.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/197682.html</trackback:ping><description><![CDATA[<strong>转载自:</strong><a style="color: red" href="http://www.oschina.net/code/snippet_196503_6933"><strong>http://www.oschina.net/code/snippet_196503_6933<br /><br /></strong></a><br /><strong>头文件:<br /></strong>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img id="Codehighlighter1_0_112_Open_Image" onclick="this.style.display='none'; Codehighlighter1_0_112_Open_Text.style.display='none'; Codehighlighter1_0_112_Closed_Image.style.display='inline'; Codehighlighter1_0_112_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_0_112_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_0_112_Closed_Text.style.display='none'; Codehighlighter1_0_112_Open_Image.style.display='inline'; Codehighlighter1_0_112_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_0_112_Closed_Text">/**/</span><span id="Codehighlighter1_0_112_Open_Text"><span style="color: #808080">/////////////////////////////////////////////////////////////////////</span><span style="color: #008000">//<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" /></span><span style="color: #808080">///</span><span style="color: #008000">/audio_decode.h&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2010-11-15&nbsp;by&nbsp;lishen</span><span style="color: #808080"></span></span><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><span style="color: #000000">#ifndef&nbsp;_AUDIODECODE_H_<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">#define</span><span style="color: #000000">&nbsp;_AUDIODECODE_H_</span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />#include&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">../lib/neaacdec.h</span><span style="color: #000000">"</span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />typedef&nbsp;</span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;_ADecode<br /><img id="Codehighlighter1_215_282_Open_Image" onclick="this.style.display='none'; Codehighlighter1_215_282_Open_Text.style.display='none'; Codehighlighter1_215_282_Closed_Image.style.display='inline'; Codehighlighter1_215_282_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_215_282_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_215_282_Closed_Text.style.display='none'; Codehighlighter1_215_282_Open_Image.style.display='inline'; Codehighlighter1_215_282_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_215_282_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_215_282_Open_Text"><span style="color: #000000">{<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;NeAACDecHandle&nbsp;&nbsp;m_hAac;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;audio&nbsp;decode&nbsp;handle&nbsp;</span><span style="color: #008000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_init;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span><span style="color: #000000">ADecode;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />typedef&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;(</span><span style="color: #000000">*</span><span style="color: #000000">audio_decode_event)(DWORD&nbsp;arg1,&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">buf,&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;len);<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />ADecode</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;ADecode_Open&nbsp;();<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;ADecode_Close&nbsp;(ADecode</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;adecode);<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;ADecode_Decode&nbsp;(ADecode</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;adecode,&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">buf,&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;buf_len,&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;audio_decode_event&nbsp;fnt,&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;arg);<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">#endif</span></div><br /><br /><strong>实现文件:</strong><br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img id="Codehighlighter1_0_114_Open_Image" onclick="this.style.display='none'; Codehighlighter1_0_114_Open_Text.style.display='none'; Codehighlighter1_0_114_Closed_Image.style.display='inline'; Codehighlighter1_0_114_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_0_114_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_0_114_Closed_Text.style.display='none'; Codehighlighter1_0_114_Open_Image.style.display='inline'; Codehighlighter1_0_114_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_0_114_Closed_Text">/**/</span><span id="Codehighlighter1_0_114_Open_Text"><span style="color: #808080">/////////////////////////////////////////////////////////////////////</span><span style="color: #008000">//<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" /></span><span style="color: #808080">///</span><span style="color: #008000">/audio_decode.cpp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2010-11-15&nbsp;by&nbsp;lishen</span><span style="color: #808080"></span></span><br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" /><span style="color: #000000">#include&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">../common/common.h</span><span style="color: #000000">"</span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" />#include&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">windows.h</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" />#include&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">stdio.h</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" />#include&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">audio_decode.h</span><span style="color: #000000">"</span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" />#pragma&nbsp;comment(lib,&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">libfaad2.lib</span><span style="color: #000000">"</span><span style="color: #000000">)<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" />ADecode</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;ADecode_Open&nbsp;()<br /><img id="Codehighlighter1_274_536_Open_Image" onclick="this.style.display='none'; Codehighlighter1_274_536_Open_Text.style.display='none'; Codehighlighter1_274_536_Closed_Image.style.display='inline'; Codehighlighter1_274_536_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_274_536_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_274_536_Closed_Text.style.display='none'; Codehighlighter1_274_536_Open_Image.style.display='inline'; Codehighlighter1_274_536_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_274_536_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_274_536_Open_Text"><span style="color: #000000">{<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;NeAACDecHandle&nbsp;hAac&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;NeAACDecOpen();<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;NeAACDecConfigurationPtr&nbsp;conf&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;NeAACDecGetCurrentConfiguration(hAac);<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;NeAACDecSetConfiguration(hAac,&nbsp;conf);<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;ADecode</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;adecode&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;ADecode&nbsp;();<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;adecode</span><span style="color: #000000">-&gt;</span><span style="color: #000000">m_hAac&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;hAac;<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;adecode</span><span style="color: #000000">-&gt;</span><span style="color: #000000">m_init&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;adecode;<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;ADecode_Close&nbsp;(ADecode</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;adecode)<br /><img id="Codehighlighter1_576_683_Open_Image" onclick="this.style.display='none'; Codehighlighter1_576_683_Open_Text.style.display='none'; Codehighlighter1_576_683_Closed_Image.style.display='inline'; Codehighlighter1_576_683_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_576_683_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_576_683_Closed_Text.style.display='none'; Codehighlighter1_576_683_Open_Image.style.display='inline'; Codehighlighter1_576_683_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_576_683_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_576_683_Open_Text"><span style="color: #000000">{<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(adecode</span><span style="color: #000000">-&gt;</span><span style="color: #000000">m_hAac&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;NULL)<br /><img id="Codehighlighter1_612_652_Open_Image" onclick="this.style.display='none'; Codehighlighter1_612_652_Open_Text.style.display='none'; Codehighlighter1_612_652_Closed_Image.style.display='inline'; Codehighlighter1_612_652_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_612_652_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_612_652_Closed_Text.style.display='none'; Codehighlighter1_612_652_Open_Image.style.display='inline'; Codehighlighter1_612_652_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_612_652_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_612_652_Open_Text"><span style="color: #000000">{<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NeAACDecClose(adecode</span><span style="color: #000000">-&gt;</span><span style="color: #000000">m_hAac);<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;adecode;<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;ADecode_Decode&nbsp;(ADecode</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;adecode,&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">buf,&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;buf_len,&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;audio_decode_event&nbsp;fnt,&nbsp;DWORD&nbsp;arg)<br /><img id="Codehighlighter1_796_1775_Open_Image" onclick="this.style.display='none'; Codehighlighter1_796_1775_Open_Text.style.display='none'; Codehighlighter1_796_1775_Closed_Image.style.display='inline'; Codehighlighter1_796_1775_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_796_1775_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_796_1775_Closed_Text.style.display='none'; Codehighlighter1_796_1775_Open_Image.style.display='inline'; Codehighlighter1_796_1775_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_796_1775_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_796_1775_Open_Text"><span style="color: #000000">{<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;ret&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;NeAACDecFrameInfo&nbsp;hInfo;<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(adecode</span><span style="color: #000000">-&gt;</span><span style="color: #000000">m_init&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">)<br /><img id="Codehighlighter1_870_1054_Open_Image" onclick="this.style.display='none'; Codehighlighter1_870_1054_Open_Text.style.display='none'; Codehighlighter1_870_1054_Closed_Image.style.display='inline'; Codehighlighter1_870_1054_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_870_1054_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_870_1054_Closed_Text.style.display='none'; Codehighlighter1_870_1054_Open_Image.style.display='inline'; Codehighlighter1_870_1054_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_870_1054_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_870_1054_Open_Text"><span style="color: #000000">{<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;adecode</span><span style="color: #000000">-&gt;</span><span style="color: #000000">m_init&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">1</span><span style="color: #000000">;<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;samplerate;<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;channels;<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NeAACDecInit&nbsp;(adecode</span><span style="color: #000000">-&gt;</span><span style="color: #000000">m_hAac,&nbsp;(unsigned&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">)&nbsp;buf,&nbsp;buf_len,&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">samplerate,&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">channels);<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" /><br /><img id="Codehighlighter1_1081_1083_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1081_1083_Open_Text.style.display='none'; Codehighlighter1_1081_1083_Closed_Image.style.display='inline'; Codehighlighter1_1081_1083_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_1081_1083_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_1081_1083_Closed_Text.style.display='none'; Codehighlighter1_1081_1083_Open_Image.style.display='inline'; Codehighlighter1_1081_1083_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">short</span><span style="color: #000000">&nbsp;buf1[</span><span style="color: #000000">1024</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">4</span><span style="color: #000000">]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_1081_1083_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_1081_1083_Open_Text"><span style="color: #000000">{</span><span style="color: #000000">0</span><span style="color: #000000">}</span></span><span style="color: #000000">;<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;buf_off&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">p&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(unsigned&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">)&nbsp;buf;<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">do</span><span style="color: #000000">&nbsp;<br /><img id="Codehighlighter1_1155_1736_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1155_1736_Open_Text.style.display='none'; Codehighlighter1_1155_1736_Closed_Image.style.display='inline'; Codehighlighter1_1155_1736_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_1155_1736_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_1155_1736_Closed_Text.style.display='none'; Codehighlighter1_1155_1736_Open_Image.style.display='inline'; Codehighlighter1_1155_1736_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_1155_1736_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_1155_1736_Open_Text"><span style="color: #000000">{<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">out</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;NeAACDecDecode&nbsp;(adecode</span><span style="color: #000000">-&gt;</span><span style="color: #000000">m_hAac,&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">hInfo,&nbsp;p,&nbsp;buf_len);<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;((hInfo.error&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">)&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;(hInfo.samples&nbsp;</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">))<br /><img id="Codehighlighter1_1294_1673_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1294_1673_Open_Text.style.display='none'; Codehighlighter1_1294_1673_Closed_Image.style.display='inline'; Codehighlighter1_1294_1673_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_1294_1673_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_1294_1673_Closed_Text.style.display='none'; Codehighlighter1_1294_1673_Open_Image.style.display='inline'; Codehighlighter1_1294_1673_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_1294_1673_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_1294_1673_Open_Text"><span style="color: #000000">{<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p&nbsp;</span><span style="color: #000000">+=</span><span style="color: #000000">&nbsp;hInfo.bytesconsumed;&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf_len&nbsp;</span><span style="color: #000000">-=</span><span style="color: #000000">&nbsp;hInfo.bytesconsumed;<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;distill&nbsp;wave</span><span style="color: #008000"><br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">short</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">p1&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;buf1,&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">p2&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(</span><span style="color: #0000ff">short</span><span style="color: #000000">*</span><span style="color: #000000">)&nbsp;</span><span style="color: #0000ff">out</span><span style="color: #000000">;<br /><img id="Codehighlighter1_1480_1503_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1480_1503_Open_Text.style.display='none'; Codehighlighter1_1480_1503_Closed_Image.style.display='inline'; Codehighlighter1_1480_1503_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_1480_1503_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_1480_1503_Closed_Text.style.display='none'; Codehighlighter1_1480_1503_Open_Image.style.display='inline'; Codehighlighter1_1480_1503_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;k&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(hInfo.samples&nbsp;</span><span style="color: #000000">/</span><span style="color: #000000">&nbsp;hInfo.channels);&nbsp;k;&nbsp;k&nbsp;</span><span style="color: #000000">--</span><span style="color: #000000">)</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_1480_1503_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_1480_1503_Open_Text"><span style="color: #000000">{</span><span style="color: #000000">*</span><span style="color: #000000">p1&nbsp;</span><span style="color: #000000">++</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">p2;&nbsp;p2&nbsp;</span><span style="color: #000000">+=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">2</span><span style="color: #000000">;}</span></span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">trace0&nbsp;(PROG_DEBUG,&nbsp;"%s-%d&nbsp;ADecode_decode&nbsp;%d.",&nbsp;__FILE__,&nbsp;__LINE__,&nbsp;len);<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;put&nbsp;out&nbsp;wave</span><span style="color: #008000"><br /><img id="Codehighlighter1_1623_1669_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1623_1669_Open_Text.style.display='none'; Codehighlighter1_1623_1669_Closed_Image.style.display='inline'; Codehighlighter1_1623_1669_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_1623_1669_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_1623_1669_Closed_Text.style.display='none'; Codehighlighter1_1623_1669_Open_Image.style.display='inline'; Codehighlighter1_1623_1669_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif"></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(fnt&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">)</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_1623_1669_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_1623_1669_Open_Text"><span style="color: #000000">{ret&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;fnt&nbsp;(arg,&nbsp;(</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">)&nbsp;buf1,&nbsp;hInfo.samples);}</span></span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(hInfo.error&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">)<br /><img id="Codehighlighter1_1706_1733_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1706_1733_Open_Text.style.display='none'; Codehighlighter1_1706_1733_Closed_Image.style.display='inline'; Codehighlighter1_1706_1733_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_1706_1733_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_1706_1733_Closed_Text.style.display='none'; Codehighlighter1_1706_1733_Open_Image.style.display='inline'; Codehighlighter1_1706_1733_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_1706_1733_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_1706_1733_Open_Text"><span style="color: #000000">{<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">;<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">break</span><span style="color: #000000">;<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #0000ff">while</span><span style="color: #000000">&nbsp;(buf_len&nbsp;</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">);<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;ret;<br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" /></span></div><br /><img src ="http://www.cppblog.com/tx7do/aggbug/197682.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2013-02-02 17:51 <a href="http://www.cppblog.com/tx7do/archive/2013/02/02/197682.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>waveInReset/waveOutReset死锁原因与解决方案</title><link>http://www.cppblog.com/tx7do/archive/2013/01/21/197429.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Sun, 20 Jan 2013 18:17:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2013/01/21/197429.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/197429.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2013/01/21/197429.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/197429.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/197429.html</trackback:ping><description><![CDATA[<div><strong style="color: red">转载自：</strong><a style="color: red" href="http://blog.csdn.net/soliddream66/article/details/5353960"><strong>http://blog.csdn.net/soliddream66/article/details/5353960</strong></a><br />
<br />
<h2 style="text-align: left; padding-bottom: 0px; line-height: 26px; widows: 2; text-transform: none;  font-variant: normal; font-style: normal; text-indent: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; padding-top: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">问题背景<br />
</h2>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">录音播音实际需求</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">1、随时终止</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">2、录音并非文件，而是形成rtp发送</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">3、播音并非源于文件，而是源于rtp</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">因此Waveform audio使用的buffer较小，不断的装载/发送 buffer,终止的时候Reset并且close.</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">大致如下调用的循环</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">录音</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">waveInUnprepareHeader</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">waveInPrepareHeader</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">waveInAddBuffer</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">播音</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">waveOutUnprepareHeader</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">waveOutPrepareHeader</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">waveOutWrite</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">循环周期40ms，我采用的是回调函数。问题是有时候调用waveInReset/waveOutReset会形成死锁，调用waveInReset/waveOutReset的线程与回调函数所在的线程死锁在一块了。</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;</p>
<h2 style="text-align: left; padding-bottom: 0px; line-height: 26px; widows: 2; text-transform: none;  font-variant: normal; font-style: normal; text-indent: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; padding-top: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><a style="color: rgb(51,102,153)" name="t1"></a>原因分析</h2>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">这方面网上有文章提到，就是调用waveInReset/waveOutReset的同时调用了录音/播音循环调用的某个函数会形成死锁。我再稍作解释下，我们知道buffer满了或是调用Reset都会触发消息（回调函数方式的话就是MM_WOM_DONE/MM_WIM_DATA），由于调用waveInReset/waveOutReset所在的线程，与回调函数所在的线程不是一个线程，因此很容易撞车，也就是说，你调用reset的时候，另一个线程正好在处理MM_WOM_DONE/MM_WIM_DATA，于是就这样死锁了。</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;</p>
<h2 style="text-align: left; padding-bottom: 0px; line-height: 26px; widows: 2; text-transform: none;  font-variant: normal; font-style: normal; text-indent: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; padding-top: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><a style="color: rgb(51,102,153)" name="t2"></a>解决方案</h2>
<h3 style="text-align: left; padding-bottom: 0px; line-height: 26px; widows: 2; text-transform: none;  font-variant: normal; font-style: normal; text-indent: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; padding-top: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><a style="color: rgb(51,102,153)" name="t3"></a>方案一<br />
</h3>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">先加上标记(假设标记bReset:bool)，令bReset为true;</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">标记作用如下</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">if(!bReset)</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">{</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">录音</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">waveInUnprepareHeader</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">waveInPrepareHeader</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">waveInAddBuffer</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">播音</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">waveOutUnprepareHeader</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">waveOutPrepareHeader</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">waveOutWrite</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">}</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">延时调用waveInReset/waveOutReset，延时时间长度以循环周期为妙，我这个例子中也就是采用40ms。</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">当然也可以采用临界保护。</p>
<h3 style="text-align: left; padding-bottom: 0px; line-height: 26px; widows: 2; text-transform: none;  font-variant: normal; font-style: normal; text-indent: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; padding-top: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><a style="color: rgb(51,102,153)" name="t4"></a><br />
</h3>
<h3 style="text-align: left; padding-bottom: 0px; line-height: 26px; widows: 2; text-transform: none;  font-variant: normal; font-style: normal; text-indent: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; padding-top: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><a style="color: rgb(51,102,153)" name="t5"></a>方案二</h3>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">换一个角度去考虑问题，之所以死锁，是因为两个线程冲突了的缘故，所以可以建立一个线程</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">录音</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">waveInUnprepareHeader</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">waveInPrepareHeader</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">waveInAddBuffer</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">播音</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">waveOutUnprepareHeader</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">waveOutPrepareHeader</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">waveOutWrite</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;</p>
<p style="text-align: left; widows: 2; text-transform: none;  text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">与waveInReset/waveOutReset都放到这个线程去处理，自然不会发生死锁了。</p>
</div><img src ="http://www.cppblog.com/tx7do/aggbug/197429.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2013-01-21 02:17 <a href="http://www.cppblog.com/tx7do/archive/2013/01/21/197429.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>运动估计与运动补偿</title><link>http://www.cppblog.com/tx7do/archive/2013/01/15/197277.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Mon, 14 Jan 2013 21:43:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2013/01/15/197277.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/197277.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2013/01/15/197277.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/197277.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/197277.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 转载自：http://blog.sina.com.cn/s/blog_4b700c4c0100nhgo.html运动补偿是通过先前的局部图像来预测、补偿当前的局部图像，它是减少帧序列冗余信息的有效方法。运动估计是从视频序列中抽取运动信息的一整套技术。运动估计与运动补偿技术　　　　MPEG-4采用I-VOP、P-VOP、B-VOP三种帧格式来表征不同的运动补偿类型。它采用了H.263中的半像...&nbsp;&nbsp;<a href='http://www.cppblog.com/tx7do/archive/2013/01/15/197277.html'>阅读全文</a><img src ="http://www.cppblog.com/tx7do/aggbug/197277.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2013-01-15 05:43 <a href="http://www.cppblog.com/tx7do/archive/2013/01/15/197277.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DirectDraw：lpitch的理解</title><link>http://www.cppblog.com/tx7do/archive/2013/01/14/197267.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Mon, 14 Jan 2013 10:29:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2013/01/14/197267.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/197267.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2013/01/14/197267.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/197267.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/197267.html</trackback:ping><description><![CDATA[<p style="padding-bottom: 0px; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font: 14px/21px tahoma, helvetica, arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(69,69,69); word-spacing: 0px; padding-top: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><strong style="color: red">转载自：</strong><a style="color: red" href="http://hi.baidu.com/daoguchengshu/item/06aa4a09d3ca7810ebfe3815"><strong>http://hi.baidu.com/daoguchengshu/item/06aa4a09d3ca7810ebfe3815</strong></a><br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Apple-converted-space">&nbsp;</span><strong>lpitch是结构体DDSURFACEDESC2的一项，这个结构体描述了页面/表面的一些信息。</strong></p>
<p style="padding-bottom: 0px; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font: 14px/21px tahoma, helvetica, arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(69,69,69); word-spacing: 0px; padding-top: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lpitch一般译做步幅(stride)或内存宽度(memory width)。注意，它与DDSURFACEDESC2结构体中的另一项dwWidth的意义是不一样的。</strong></p>
<p style="padding-bottom: 0px; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font: 14px/21px tahoma, helvetica, arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(69,69,69); word-spacing: 0px; padding-top: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;&nbsp;&nbsp;&nbsp;<span class="Apple-converted-space">&nbsp;</span><strong>lpitch的单位是字节，dwWidth的单位是像素。所以，一个640&#215;480&#215;8（640&#215;480个像素，每像素用8位，即一个字节表示）页面，dwWidth=640 像素（字节）。但是，此时Lpitch不一定就等于640（字节）！同样一个640&#215;480&#215;16的页面，它的Lpitch值也不一定等于640&#215;2（字节）。</strong></p>
<p style="padding-bottom: 0px; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font: 14px/21px tahoma, helvetica, arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(69,69,69); word-spacing: 0px; padding-top: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><strong>&nbsp;&nbsp; 这是因为，Lpitch中的字节数有时还包含了高速缓冲区的内存字节数。如下图：</strong></p>
<p style="padding-bottom: 0px; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font: 14px/21px tahoma, helvetica, arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(69,69,69); word-spacing: 0px; padding-top: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/tx7do/DirectDraw_lpitch.jpg" width="425" height="123" /></strong></p>
<p style="padding-bottom: 0px; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font: 14px/21px tahoma, helvetica, arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(69,69,69); word-spacing: 0px; padding-top: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 通过以上图可以看到，页面外面还有一段额外内存，而这段内存是未知的；所以说，假如一个640&#215;480&#215;8的页面，它的dwWidth值是640，但是，它的Lpitch值应该是640+x，x就是高速缓冲区Cache占用的内存。</strong></p>
<p style="padding-bottom: 0px; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font: 14px/21px tahoma, helvetica, arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(69,69,69); word-spacing: 0px; padding-top: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 所以，如果要访问这个页面缓冲区的第y行的第x个像素,应该这样：</strong></p>
<p style="padding-bottom: 0px; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font: 14px/21px tahoma, helvetica, arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(69,69,69); word-spacing: 0px; padding-top: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><strong>&nbsp;&nbsp;&nbsp;&nbsp; ddsd.lpSurface[x+y*ddsd.lpitch]<br /></strong></p><br class="Apple-interchange-newline" /><img src ="http://www.cppblog.com/tx7do/aggbug/197267.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2013-01-14 18:29 <a href="http://www.cppblog.com/tx7do/archive/2013/01/14/197267.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>cocos2dx 内存管理</title><link>http://www.cppblog.com/tx7do/archive/2012/12/15/196327.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Sat, 15 Dec 2012 07:18:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2012/12/15/196327.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/196327.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2012/12/15/196327.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/196327.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/196327.html</trackback:ping><description><![CDATA[<strong style="color: red">转载自：</strong><a style="color: red" href="http://blog.csdn.net/ring0hx/article/details/7946397"><strong>http://blog.csdn.net/ring0hx/article/details/7946397</strong></a><a href="http://blog.csdn.net/ring0hx/article/details/7946397"><strong><br /></strong></a><br />
<div style="text-align: left; widows: 2; text-transform: none; text-indent: 0px; font: 16px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">cocos2dx的内存管理移植自Objective-C， 对于没有接触过OC的C++开发人员来说是挺迷惑的。不深入理解内存管理是无法写出好的C++程序的，我用OC和cocos2dx也有一段时间了，在此总结一下，希望对想用cocos2dx开发游戏的朋友有所帮助。</div>
<div style="text-align: left; widows: 2; text-transform: none; text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">
<div style="font-size: 16px"><br /></div>
<div style="font-size: 16px">C++的动态内存管理一般建议遵循谁申请谁释放的原则，即谁通过new操作符创建了对象，谁就负责通过delete来释放对象。如果对象的生命周期在一个函数内，这很容易做到，在函数返回前delete就行了。但一般我们在函数中new出来的对象的生命周期都会超出该函数体(例如作为函数的返回值)，否则我们可以直接在栈上创建对象，不需要使用动态内存，也省去了内存管理的麻烦(当然大对象是不适合在栈上分配的)。如果对象的生命周期超出了创建对象的函数，我们就很难再遵循谁申请谁释放的原则了，我们必须在函数外的某个合适的地方释放对象，如果这个对象同时被多个对象引用，问题就很复杂了，必须保证所有该对象的引用者都不再需要它了才可以释放，在实际使用中这点是很难保证的。于是，各种内存管理技术应运而生了：垃圾回收器，智能指针，引用计数...... cocos2dx移植于Objective-C，因此和OC一样使用了比较原始的引用计数的方法来管理内存。</div>
<div style="font-size: 16px"><br /></div>
<div style="font-size: 16px">cocos2dx通过CCObject和CCPoolManager来实现内存管理。所有使用cocos2dx引用计数机制的类都必须派生自CCObject。CCObject有一个计数器成员变量m_uReference，当CCObject被构造时m_uReference=1，表示该对象被引用1次。CCObject的<span style="color: rgb(17,17,17)">retain方法可以使计数器加1，release方法可以使计数器减1。当计数器减到0时release方法会通过delete this来销毁自己。</span></div>
<div style="font-size: 16px"><span style="color: rgb(17,17,17)"><br /></span></div>
<div style="font-size: 16px"><span style="color: rgb(1,1,1)"><strong>手动内存管理</strong></span></div>
<div style="font-size: 16px"><span style="color: rgb(17,17,17)">使用retain和release，我们可以手动管理内存, 通过new 创建的对象，使用release来释放。 
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" /><span style="color: #000000">CCObject&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">obj</span><span style="color: #000000">=</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;CCObject();<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" /><img src="http://www.cppblog.com/Images/dot.gif"  alt="" />&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" />obj</span><span style="color: #000000">-&gt;</span><span style="color: #000000">release();</span></div></span>和new\delete需配对使用一样，new\release也要配对使用才可确保内存被释放。有人会说这个把delete换成release有意义吗？需要注意的是这个的release并不等同于delete，release只是表示引用计数减1，并不是真正销毁obj所占用的内存。只有当obj的引用计数为0时内存才会被销毁。下面的代码就展示了release和delete不同：</div><span style="font-size: 16px"></span>
<div><span style="color: rgb(255,0,0)">
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" /><span style="color: #000000">CCArray&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">array&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;CCArray::array();<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" />CCObject&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">obj&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;CCObject();</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;m_uReference=1</span><span style="color: #008000"><br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" /></span><span style="color: #000000">array</span><span style="color: #000000">-&gt;</span><span style="color: #000000">addObject(obj);&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;CCArray的addObject方法会自动调用obj的retain方法，使引用计数加1，表示拥有obj，此时m_uReference=2</span><span style="color: #008000"><br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" /></span><span style="color: #000000">obj</span><span style="color: #000000">-&gt;</span><span style="color: #000000">release();&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;这里的release和new配对，obj引用计数减1，但是并不会释放obj,&nbsp;此时m_uReference=1;</span><span style="color: #008000"><br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" /></span><span style="color: #000000">obj</span><span style="color: #000000">-&gt;</span><span style="color: #000000">doSomething();&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;在release之后我们依然可以正常使用obj，它并没有被释放</span><span style="color: #008000"><br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" /></span><span style="color: #000000">array</span><span style="color: #000000">-&gt;</span><span style="color: #000000">removeObject(obj);&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">当我们把obj从CCArray中移除时，CCArray会自动调用obj的release，此时m_uReference=0,&nbsp;obj被销毁</span><span style="color: #008000"><br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" /></span><span style="color: #000000">obj</span><span style="color: #000000">-&gt;</span><span style="color: #000000">doSomething();&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;错误，obj已经被销毁</span></div>对于手动内存管理，我们需遵循new/release，retain/release配对使用的原则，谁new，谁release；谁retain，谁release。</span>new出来的对象如果是要加入到cocos2dx集合中，添加完后一定不要忘记release，集合类已经为你retain了对象，你还是要为你的new配对release一次，否则当这个对象从集合中移除时不会被正确销毁。 
<div><br /></div>
<div style="font-size: 16px"><strong>自动内存管理</strong></div>
<div style="font-size: 16px">手动内存管理似乎比new/delete更麻烦，而且并没有解决一开始我们提到的函数内创建的对象的生命周期超出函数怎么办的问题。new和release需配对使用，那在函数内创建的对象返回前我们需要调用一次release，在这之前如果我们没有把对象加入到什么集合中，对象就被销毁了，和使用new/delete是一样的。自动内存管理就可以解决这个问题。CCObject有一个autorelease方法，如果一个对象在用new关键字创建之后调用了autorelease，我们就不必关心它的释放问题。CCPoolManager会在游戏的每一帧结束后自动释放这些autorelease的对象。CCPoolManager其实依然是通过引用计数来管理对象生命周期的，它里面有一个CCAutoreleasePool，我们调用CCObject的autorelease就是把自己加入到CCAutoreleasePool的对象数组里面。当每一帧结束的时候，CCPoolManager会将对象从数组中移除，如果这时候对象的引用计数为0，对象就自然被释放了。<span style="color: rgb(227,0,0)">对于用new关键字创建之后调用了autorelease的对象，不需要再release一次。</span></div>
<div style="font-size: 16px"><br /></div>
<div style="font-size: 16px">cocos2dx中的大部分对象都可以通过静态工厂方法来创建出这种会自动释放的对象，这是cocos2dx的一条规则，我们自己实现的类最好也遵循这样的规则，以免引起其他开发人员误会。如果一个对象是通过类的静态方法创建而不是new出来的，我们就不需要release它。</div>
<div><br /></div>
<div style="font-size: 16px">其实这里的自动并没有我们想得那么好，对于像C#，Java这种托管语言，虚拟机为你完成了所有内存管理工作，程序员完全从内存分配和释放中解脱了出来。cocos2dx的autorelease只不过每帧结束后自动在为我们释放了一次对象，<span style="color: rgb(255,0,0)">如果我们希望创建的对象在下一帧仍然可以使用，我们需要显式地retain一下这个对象或者把对象加入到集合中(集合会帮我们retain一次)</span>。既然retain了，我们还是不能忘记在适当的地方release。比较常见的用法是创建一个autorelease对象作为类成员变量，我们在通过静态方法得到实例的指针后除了赋值给类成员，还要retain一次，然后在类的析构函数中release一次。如果没有retain，以后使用该成员的时候就会因为对象被销毁而发生内存访问错误，这是新手很容易遇到的陷阱。</div></div></div><img src ="http://www.cppblog.com/tx7do/aggbug/196327.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2012-12-15 15:18 <a href="http://www.cppblog.com/tx7do/archive/2012/12/15/196327.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>directsound抓取麦克风PCM数据封装类 </title><link>http://www.cppblog.com/tx7do/archive/2012/11/23/195585.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Thu, 22 Nov 2012 16:11:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2012/11/23/195585.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/195585.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2012/11/23/195585.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/195585.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/195585.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 转载自:http://blog.chinaunix.net/uid-8272118-id-2033248.html网上有很多方法从麦克风读取PCM数据，不想一一举例。只是在这里发布一个我自己写的directsound的麦克风PCM数据采集类，通过它，可以很方便的利用directsound技术把麦克风的数据采集到，而且本身，开发者不必太在意自己会不会directsound编程，可以很方便的让开发...&nbsp;&nbsp;<a href='http://www.cppblog.com/tx7do/archive/2012/11/23/195585.html'>阅读全文</a><img src ="http://www.cppblog.com/tx7do/aggbug/195585.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2012-11-23 00:11 <a href="http://www.cppblog.com/tx7do/archive/2012/11/23/195585.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Speex手册----Speex编/解码API的使用(libspeex)</title><link>http://www.cppblog.com/tx7do/archive/2012/11/22/195513.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Wed, 21 Nov 2012 16:03:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2012/11/22/195513.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/195513.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2012/11/22/195513.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/195513.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/195513.html</trackback:ping><description><![CDATA[<div><strong style="color: red">转载自:</strong><a style="color: red" href="http://blog.csdn.net/dotscylla/article/details/4426220"><strong>http://blog.csdn.net/dotscylla/article/details/4426220</strong></a>
<div style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 20px 0px 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" id="article_content">
<p><span style="font-size: small"><strong>前言：</strong>Speex官网：</span><a style="color: rgb(51,102,153); text-decoration: none" href="http://speex.org/"><span style="color: rgb(51,102,153)"><span style="font-size: small">http://speex.org/</span></span></a><span style="font-size: small">&nbsp;可以再Documentation下找到PDF版或HTML OL版的英文手册。可能会由于英文技能的匮乏或语音解码领域的不熟悉会有翻译错误，所以每段我都会付上英文原段落，也望各位发现后能够不吝赐教，大家共同进步。</span></p>
<p>&nbsp;</p>
<p><span style="font-size: small">PS: 1) 如需转载，注明出处，不胜感激; 2) 如侵您版权，及时通知，速删之</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体"><span style="font-size: small"><a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/dotscylla/article/details/4426220#Decoding"></a></span></span></p>
<p><span style="font-family: 宋体"></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small"><a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/dotscylla/article/details/4426220#Encoding">5.1 编码</a></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small"><a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/dotscylla/article/details/4426220#Decoding">5.2 解码</a></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small"><a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/dotscylla/article/details/4426220#CodecOption">5.3 编解码选项(speex_*_ctl)</a></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small"><a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/dotscylla/article/details/4426220#ModeQuery">5.4 模式查询</a></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small"><a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/dotscylla/article/details/4426220#Packing&amp;In-band Signalling">5.5 封包和带内信令</a></span></span></p><a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/dotscylla/article/details/4426220#Packing&amp;In-band Signalling"></a>
<p>&nbsp;</p>
<p><span style="font-family: 宋体"><span style="font-size: small"><a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/dotscylla/article/details/4426220#Markup"><span style="font-family: arial, helvetica, sans-serif">补充</span></a></span></span></p>
<p>&nbsp;</p><pre style="word-wrap: break-word; white-space: pre-wrap"><span style="font-size: small"><a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/dotscylla/article/details/4426220#PostScript">后记</a></span></pre>
<p>&nbsp;</p>
<p><span style="font-size: small">The libspeex library contains all the functions for encoding and decoding speech with the Speex codec. When linking on a UNIX system, one must add -lspeex -lm to the compiler command line. One important thing to know is that libspeex calls are reentrant, but not thread-safe. That means that it is fine to use calls from many threads, but calls using the same state from multiple threads must be protected by mutexes. Examples of code can also be found in Appendix A and the complete API documentation is included in the Documentation section of the Speex website (<a style="color: rgb(51,102,153); text-decoration: none" href="http://www.speex.org/">http://www.speex.org/</a>).</span></p>
<p style="text-indent: 21pt"><span style="font-size: small">Speex<span style="font-family: 宋体">编解码器的</span>libspeex<span style="font-family: 宋体">包囊括了所有的语音编码和解码函数。在</span>Linux<span style="font-family: 宋体">系统中连接时，必须在编译器命令行中加入</span>-lspeex &#8211;lm<span style="font-family: 宋体">。需要知道的是，虽然</span>libspeex<span style="font-family: 宋体">的函数调用是可重入的，但不是线程安全的，所以在多线程调用时，如果使用共享资源需要进行互斥保护。附录</span>A<span style="font-family: 宋体">中有代码实例，在</span>Speex<span style="font-family: 宋体">站点(</span><a style="color: rgb(51,102,153); text-decoration: none" href="http://www.speex.org/">http://www.speex.org/</a>&nbsp;)<span style="font-family: 宋体">的文档部分能下到完整的</span>API<span style="font-family: 宋体">文档。</span></span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h2><a style="color: rgb(51,102,153); text-decoration: none" name="t0"></a><span style="font-family: Arial"><a style="color: rgb(51,102,153); text-decoration: none" name="Encoding"></a>5.1&nbsp;</span><span style="font-family: 黑体">编码</span></h2>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">In order to encode speech using Speex, one first needs to:<br />#include &lt;speex/speex.h&gt;<br />Then in the code, a Speex bit-packing struct must be declared, along with a Speex encoder state:<br />SpeexBits bits;</span></span></p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">void *enc_state;<br />The two are initialized by:<br />speex_bits_init(&amp;bits);<br />enc_state = speex_encoder_init(&amp;speex_nb_mode);<br />For wideband coding, speex_nb_mode will be replaced by speex_wb_mode. In most cases, you will need to know the frame size used at the sampling rate you are using. You can get that value in the frame_size variable (expressed in samples, not<br />bytes) with:<br />speex_encoder_ctl(enc_state,SPEEX_GET_FRAME_SIZE,&amp;frame_size);<br />In practice, frame_size will correspond to 20 ms when using 8, 16, or 32 kHz sampling rate. There are many parameters that can be set for the Speex encoder, but the most useful one is the quality parameter that controls the quality vs bit-rate tradeoff.<br />This is set by:<br />speex_encoder_ctl(enc_state,SPEEX_SET_QUALITY,&amp;quality);<br />where quality is an integer value ranging from 0 to 10 (inclusively). The mapping between quality and bit-rate is described in Fig. 9.2 for narrowband.<br />Once the initialization is done, for every input frame:<br />speex_bits_reset(&amp;bits);<br />speex_encode_int(enc_state, input_frame, &amp;bits);<br />nbBytes = speex_bits_write(&amp;bits, byte_ptr, MAX_NB_BYTES);<br />where input_frame is a (short *) pointing to the beginning of a speech frame, byte_ptr is a (char *) where the encoded frame will be written,MAX_NB_BYTES is the maximumnumber of bytes that can be written to byte_ptr without causing an overflow and nbBytes is the number of bytes actually written to byte_ptr (the encoded size in bytes). Before calling speex_bits_write, it is possible to find the number of bytes that need to be written by calling speex_bits_nbytes(&amp;bits), which returns a number of bytes.<br />It is still possible to use the speex_encode() function, which takes a (float *) for the audio. However, this would make an eventual port to an FPU-less platform (like ARM) more complicated. Internally, speex_encode() and speex_encode_int() are processed in the same way. Whether the encoder uses the fixed-point version is only decided by the compile-time flags, not at the API level.<br />After you&#8217;re done with the encoding, free all resources with:<br />speex_bits_destroy(&amp;bits);<br />speex_encoder_destroy(enc_state);<br />That&#8217;s about it for the encoder.</span></span></p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">使用Speex进行语音编码，首先要：</span></span></p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">#include &lt; speex/speex.h &gt;</span></span></p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">在代码中，需要声明Speex比特包结构体，同时设置Speex编码器状态：</span></span></p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SpeexBits bits;</span></span></p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">void * enc_state;</span></span></p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">初始化两变量：</span></span></p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">speex_bits_init( &amp;bits );</span></span></p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">enc_state = speex_encoder_init( &amp;speex_nb_mode );</span></span></p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">用speex_wb_mode代替为speex_nb_mode，即可转换为宽带编码。很多时候，你在使用采样率的需要知道帧的大小，可以通过变量frame_size（用样本中的单位表示，不以字节为单位）获得，调用下面函数：</span></span></p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">speex_encoder_ctl( enc_state, SPEEX_GET_FRAME_SIZE, &amp;frame_size );</span></span></p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">实践表明，在采用8、16或32kHz采样率的时候，frame_size大约对应于20ms。Speex编码器还有很多参数可以设置，其中最有用的一个是质量参数，控制着比特率（bit-rate）交换的质量，通过下面函数设置：</span></span><br /><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">speex_encoder_ctl( enc_state, SPEEX_SET_QUALITY, &amp;quality );</span></span></p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">quality是一个0～10（包含10）范围内的整数，窄带（narrowband）的质量和比特率（bit-rate）的对应关系如图9.2所示。</span></span></p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">初始化成功后，对于每帧的输入：</span></span></p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">speex_bits_reset( &amp;bits );</span></span></p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">speex_encode_int( enc_state, input_frame, &amp;bits );</span></span></p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">nbBytes = speex_bits_write( &amp;bits, byte_ptr, MAX_NB_BYTES );</span></span></p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">其中，input_frame是指向每个Speex帧开始的short型指针，byte_ptr是将写入已被编码的帧的char型指针，MAX_NB_BYTES是byte_ptr在不导致溢出时可被写入的最大字节数，nbBytes是byte_ptr实际被写入的字节数(编码大小以字节为单位)。在调用speex_bits_write之前，可能会通过speex_bits_nbytes(&amp;bits)返回的字节数获得需要被写入的字节数，也可能使用speex_encode()&nbsp;函数，它接受一个携带音频数据的float*型参数。不过这将使缺少浮点运算单元（FPU）的平台（如ARM）变的更为复杂。实际上，speex_encode和speex_encode_int()用同样的方法处理，编码器是否使用定点数取决于编译期的标志位，不由API来控制。</span></span></p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">完成编码后，释放所有资源：</span></span><br /><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">speex_bits_destroy( &amp;bits );</span></span></p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">speex_encoder_destroy( enc_state );</span></span></p>
<p><span style="font-size: 10.5pt"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">这是关于编码的部分。</span></span></span></p>
<p>&nbsp;&nbsp;</p>
<h2><a style="color: rgb(51,102,153); text-decoration: none" name="t1"></a><a style="color: rgb(51,102,153); text-decoration: none" name="Decoding"></a>5.2&nbsp;<span style="font-family: 黑体">解码</span></h2>
<p><span style="font-size: small">In order to decode speech using Speex, you first need to:<br />#include &lt;speex/speex.h&gt;<br />You also need to declare a Speex bit-packing struct<br />SpeexBits bits;<br />and a Speex decoder state<br />void *dec_state;<br />The two are initialized by:<br />speex_bits_init(&amp;bits);<br />dec_state = speex_decoder_init(&amp;speex_nb_mode);<br />For wideband decoding, speex_nb_mode will be replaced by speex_wb_mode. If you need to obtain the size of the frames that will be used by the decoder, you can get that value in the frame_size variable (expressed in samples, not bytes) with:<br />speex_decoder_ctl(dec_state, SPEEX_GET_FRAME_SIZE, &amp;frame_size);<br />There is also a parameter that can be set for the decoder: whether or not to use a perceptual enhancer. This can be set by:<br />speex_decoder_ctl(dec_state, SPEEX_SET_ENH, &amp;enh);<br />where enh is an int with value 0 to have the enhancer disabled and 1 to have it enabled. As of 1.2-beta1, the default is now to enable the enhancer.<br />Again, once the decoder initialization is done, for every input frame:<br />speex_bits_read_from(&amp;bits, input_bytes, nbBytes);<br />speex_decode_int(dec_state, &amp;bits, output_frame);<br />where input_bytes is a (char *) containing the bit-stream data received for a frame, nbBytes is the size (in bytes) of that bit-stream, and output_frame is a (short *) and points to the area where the decoded speech frame will be written. A NULL value as the second argument indicates that we don&#8217;t have the bits for the current frame. When a frame is lost, the Speex decoder will do its best to "guess" the correct signal.<br />As for the encoder, the speex_decode() function can still be used, with a (float *) as the output for the audio. After you&#8217;re done with the decoding, free all resources with:<br />speex_bits_destroy(&amp;bits);<br />speex_decoder_destroy(dec_state);</span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif">使用Speex解码语音，首先要包含speex.h头文件。</span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">#include &lt; speex/speex.h&gt;</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">需要声明Speex比特包的结构体和Speex解码器的状态</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SpeexBits bits;</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">void* dec_state;</span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">进行初始化</span></span></span></span><br /><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">speex_bits_init( &amp;bits );</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">dec_state = speex_decoder_init( &amp;speex_nb_mode );</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">用speex_wb_mode代替speex_nb_mode，可转换为宽带（windband）解码。可能过变量frame_size来获得解码的帧大小</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">speex_decoder_ctl( dec_state, SPEEX_GET_FRAME_SIZE, &amp;frame_size );</span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">还可以能过下面函数设置是否使用&#8220;知觉增强&#8221;功能</span></span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">speex_decoder_ctl( dec_state, SPEEX_SET_ENH, &amp;enh );</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">如果enh是0则表是不启用，1则表示启用。在1.2-beta1中，默认是开启的。</span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">做完初始化工作后，则可对每个输入帧进行如下操作：</span></span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">speex_bits_read_from( &amp;bits, input_bytes, nbBytes );</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">speex_decode_int( dec_state, &amp;bits, output_frame );</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">其中,input_bytes是char型指针，包含了一帧的比特流数据，nbBytes是那帧比特流数据的大小（以字节为单位），output_frame是short型指针，指向一块内存区域，存储对语音帧的解码。第二个参数为空值（NULL）意味着没有获得到正确的比特(bit)数据，出现丢帧，Speex解码器会尽可能猜测最为准确的语音信号。</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">和编码器类似，可以用speex_decode()函数的一个float*型参数获得音频输出。</span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">完成解码后，释放掉所有资源：</span></span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">speex_bits_destory( &amp;bits );</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">speex_decoder_destory( dec_state );</span></span></span></p>
<p>&nbsp;</p>
<h2><a style="color: rgb(51,102,153); text-decoration: none" name="t2"></a><a style="color: rgb(51,102,153); text-decoration: none" name="CodecOption"></a>5.3&nbsp;<span style="font-family: 黑体">编解码选项</span>(speex_*_ctl)</h2>
<p><span style="font-size: small">The Speex encoder and decoder support many options and requests that can be accessed through the speex_encoder_ctl and<br />speex_decoder_ctl functions. These functions are similar to the ioctl system call and their prototypes are:<br />void speex_encoder_ctl(void *encoder, int request, void *ptr);<br />void speex_decoder_ctl(void *encoder, int request, void *ptr);<br />Despite those functions, the defaults are usually good for many applications and optional settings should only be used when one understands them and knows that they are needed. A common error is to attempt to set many unnecessary settings.<br />Here is a list of the values allowed for the requests. Some only apply to the encoder or the decoder. Because the last argument is of type void *, the _ctl() functions are not type safe, and shoud thus be used with care. The type spx_int32_t is the same as the C99 int32_t type.<br />SPEEX_SET_ENH&#8225; Set perceptual enhancer to on (1) or off (0) (spx_int32_t, default is on)<br />SPEEX_GET_ENH&#8225; Get perceptual enhancer status (spx_int32_t)<br />SPEEX_GET_FRAME_SIZE Get the number of samples per frame for the current mode (spx_int32_t)<br />SPEEX_SET_QUALITY&#8224; Set the encoder speech quality (spx_int32_t from 0 to 10, default is 8)<br />SPEEX_GET_QUALITY&#8224; Get the current encoder speech quality (spx_int32_t from 0 to 10)<br />SPEEX_SET_MODE&#8224; Set the mode number, as specified in the RTP spec (spx_int32_t)<br />SPEEX_GET_MODE&#8224; Get the current mode number, as specified in the RTP spec (spx_int32_t)<br />SPEEX_SET_VBR&#8224; Set variable bit-rate (VBR) to on (1) or off (0) (spx_int32_t, default is off)<br />SPEEX_GET_VBR&#8224; Get variable bit-rate (VBR) status (spx_int32_t)<br />SPEEX_SET_VBR_QUALITY&#8224; Set the encoder VBR speech quality (float 0.0 to 10.0, default is 8.0)<br />SPEEX_GET_VBR_QUALITY&#8224; Get the current encoder VBR speech quality (float 0 to 10)<br />SPEEX_SET_COMPLEXITY&#8224; Set the CPU resources allowed for the encoder (spx_int32_t from 1 to 10, default is 2)<br />SPEEX_GET_COMPLEXITY&#8224; Get the CPU resources allowed for the encoder (spx_int32_t from 1 to 10, default is 2)<br />SPEEX_SET_BITRATE&#8224; Set the bit-rate to use the closest value not exceeding the parameter (spx_int32_t in bits per second)<br />SPEEX_GET_BITRATE Get the current bit-rate in use (spx_int32_t in bits per second)<br />SPEEX_SET_SAMPLING_RATE Set real sampling rate (spx_int32_t in Hz)<br />SPEEX_GET_SAMPLING_RATE Get real sampling rate (spx_int32_t in Hz)<br />SPEEX_RESET_STATE Reset the encoder/decoder state to its original state, clearing all memories (no argument)<br />SPEEX_SET_VAD&#8224; Set voice activity detection (VAD) to on (1) or off (0) (spx_int32_t, default is off)<br />SPEEX_GET_VAD&#8224; Get voice activity detection (VAD) status (spx_int32_t)<br />SPEEX_SET_DTX&#8224; Set discontinuous transmission (DTX) to on (1) or off (0) (spx_int32_t, default is off)<br />SPEEX_GET_DTX&#8224; Get discontinuous transmission (DTX) status (spx_int32_t)<br />SPEEX_SET_ABR&#8224; Set average bit-rate (ABR) to a value n in bits per second (spx_int32_t in bits per second)<br />SPEEX_GET_ABR&#8224; Get average bit-rate (ABR) setting (spx_int32_t in bits per second)<br />SPEEX_SET_PLC_TUNING&#8224; Tell the encoder to optimize encoding for a certain percentage of packet loss (spx_int32_t in percent)<br />SPEEX_GET_PLC_TUNING&#8224; Get the current tuning of the encoder for PLC (spx_int32_t in percent)<br />SPEEX_SET_VBR_MAX_BITRATE&#8224; Set the maximum bit-rate allowed in VBR operation (spx_int32_t in bits per second)<br />SPEEX_GET_VBR_MAX_BITRATE&#8224; Get the current maximum bit-rate allowed in VBR operation (spx_int32_t in bits per second)<br />SPEEX_SET_HIGHPASS Set the high-pass filter on (1) or off (0) (spx_int32_t, default is on)<br />SPEEX_GET_HIGHPASS Get the current high-pass filter status (spx_int32_t)<br />&#8224; applies only to the encoder<br />&#8225; applies only to the decoder</span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif">Speex编码器和解码器可以通过访问speex_encoder_ctl和speex_decoder_ctl函数来设置更多选项，类似于系统函数ioctl。它们的原型是：</span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">void speex_encoder_ctl( void* encoder, int request, void* ptr );</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">void speex_decoder_ctl( void* decoder, int request, void* ptr );</span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">尽管拥有这些函数，但一般的应用程序在默认情况下就足够，如果要设置则需了解并知道为什么需要它们，勿随变设置。</span></span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">下面列出了各种需求的允许值，其中一些只能应用于编码器或解码器。因为最后一个参数是void指针，所以_ctl()函数不是类型安全的，应小心使用。spx_int32_t类型同C99中的int32_t。</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_SET_ENH：设置知觉增强，1开启，0关闭（spx_int32_t，默认开启）</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_GET_ENH：获得知觉增强状态( spx_int32_t)</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_SET_QUALITY：设置编码质量（spx_int32_t&nbsp;从0～10，默认为8&nbsp;）</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_GET_QUALITY：获得当前语音编码质量（spx_int32_t&nbsp;从0～10&nbsp;）</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_SET_MODE：设置模式，指明RTP协议规格（spx_int32_t）</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_GET_MODE：获得当前模式，指明的RTP协议规格（spx_int32_t）</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_SET_VBR：设置变比特率（VBR），1开启，0关闭（spx_int32_t，&nbsp;默认关闭）</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_GET_VBR：&nbsp;获得变比特率功能当前是否开启（spx_int32_t&nbsp;）</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_SET_VBR_QUALITY：设置变比特率语音的编码质量（浮点数从0.0～10.0,默认8.0）</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_GET_VBR_QUALITY：获得当前变比特率语音的编码质量（&nbsp;浮点数从0.0～10.0）</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_SET_COMPLEXITY：设置编码器的可用CPU资源（&nbsp;spx_int32_t从1～10，默认为2）</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_GET_COMPLEXITY：获取编码器的可用CPU资源（spx_int32_t从1～10，默认为2）</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_SET_BITRATE：设置不超过参数设置的最佳比特值(spx_int32_t&nbsp;单位bits/s )</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_GET_BITRATE：获取当前使用的比特率（&nbsp;spx_int32_t&nbsp;单位&nbsp;bits/s）</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_SET_SAMPLING_RATE：设置实时采样率（spx_int32_t&nbsp;单位&nbsp;Hz&nbsp;）</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_GET_SAMPLING_RATE：获取实时采样率（spx_int32_t&nbsp;单位&nbsp;Hz）</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_RESET_STATE：重置编/解码器到原始状态，并清除所有记忆（无参数）</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_SET_VAD：设置静音检测特性（VAD），1为打开，0为关闭（&nbsp;spx_int32_t,&nbsp;默认为关闭）</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_GET_VAD：获取静音检测是否打开（&nbsp;spx_int32_t&nbsp;）</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_SET_DTX：设计非连续性传输（DTX），1为打开，0为关闭（spx_int32_t,&nbsp;默认为关闭）</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_GET_DTX：获取非连续性传输（DTX）是否打开（spx_int32_t&nbsp;）</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_SET_ABR：设置平均比特率（ABR）值，&nbsp;单位&nbsp;bits/s(spx_int32_t，单位&nbsp;bits/s )</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_GET_ABR：获得平均比特率设置（spx_int32_t，单位bits/s&nbsp;）</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_SET_PLC_TUNING：让编码器对一定的失包率开启最优化编码（spx_int32_t，单位&nbsp;％）</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_GET_PLC_TUNING：<span style="font-family: 宋体">获取编码器为<span style="font-family: 'Times New Roman'">PLC</span><span style="font-family: 宋体">的当前调整（</span><span style="font-family: 'Times New Roman'">spx_int32_t</span><span style="font-family: 宋体">，单位％）</span></span></span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_SET_VBR_MAX_BITRATE：设置允许变比特率（VBR）使用的最大比特率（spx_int32_t，单位&nbsp;bits/s&nbsp;）</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_GET_VBR_MAX_BITRATE：获取允许变比特率（VBR）使用的最大比特率（spx_int32_t，单位&nbsp;bits/s&nbsp;）</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_SET_HIGHPASS：设置高通滤波器，1为打开，0为关闭（spx_int32_t，默认为打开）</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_GET_HIGHPASS：获取高通滤波器状态（&nbsp;spx_int32_t&nbsp;）</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">仅用于编/解码器。</span></span></span></p>
<p>&nbsp;</p>
<h2><a style="color: rgb(51,102,153); text-decoration: none" name="t3"></a><span style="font-family: Arial"><a style="color: rgb(51,102,153); text-decoration: none" name="ModeQuery"></a>5.4&nbsp;</span><span style="font-family: 黑体">模式查询</span></h2>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">Speex modes have a query system similar to the speex_encoder_ctl and speex_decoder_ctl calls. Since modes are read-only,it is only possible to get information about a particular mode. The function used to do that is:<br />void speex_mode_query(SpeexMode *mode, int request, void *ptr);</span></span></p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">类似于调用speex_encoder_ctl和speex_decoder_ctl，Speex有模式查询系统。因为模式是只读的，所以只能获得模式的详细信息。使用如下函数：</span></span></p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">void speex_mode_query( SpeexMode* mode, int request, void* ptr );</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">The admissible values for request are (unless otherwise note, the values are returned through ptr):<br />SPEEX_MODE_FRAME_SIZE Get the frame size (in samples) for the mode<br />SPEEX_SUBMODE_BITRATE Get the bit-rate for a submode number specified through ptr (integer in bps).</span></span></p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">受理的请求值（除非另有说明，要不返回值都是通过ptr）：</span></span></p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_MODE_FRAME_SIZE&nbsp;获得模式的帧大小(样本中)</span></span></p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">SPEEX_SUBMODE_BITRATE：获取通过ptr指定的子模式数量的比特率（以bps为单位的整数）</span></span></p>
<p>&nbsp;</p>
<h2><a style="color: rgb(51,102,153); text-decoration: none" name="t4"></a><a style="color: rgb(51,102,153); text-decoration: none" name="Packing&amp;In-band Signalling"></a>5.5&nbsp;<span style="font-family: 黑体">封包和带内信令</span></h2>
<p><span style="font-size: small">Sometimes it is desirable to pack more than one frame per packet (or other basic unit of storage). The proper way to do it is to call speex_encode N times before writing the stream with speex_bits_write. In cases where the number of frames is not determined by an out-of-band mechanism, it is possible to include a terminator code. That terminator consists of the code 15 (decimal) encoded with 5 bits, as shown in Table 9.2. Note that as of version 1.0.2, calling speex_bits_write automatically inserts the terminator so as to fill the last byte. This doesn&#8217;t involves any overhead and makes sure Speex can always detect when there is no more frame in a packet.</span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif">有时我们打包的数据不只一帧（或其他基本存储单元），正确做法是在用speex_bits_write写入流数据之前调用N次speex_encode。这种情况下的帧数不是由带外机制决定的，它会包含一个终结码。如表9.2所示，这个终结码是由用5bits编码的Mode 15组成。如果是1.0.2版本需注意，调用speex_bits_write时，为了填充最后字节，它会自动添加终结码。这不会增加开销，并能确保Speex一直检测到包中没有更多帧为止。</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体"><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">It is also possible to send in-band &#8220;messages&#8221; to the other side. All these messages are encoded as &#8220;pseudo-frames&#8221; of mode 14 which contain a 4-bit message type code, followed by the message. Table 5.1 lists the available codes, their meaning and the size of the message that follows. Most of these messages are requests that are sent to the encoder or decoder on the other end, which is free to comply or ignore them. By default, all in-band messages are ignored.</span></span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">当然也可以通过带内&#8220;消息&#8221;的方法，所有这些消息是作为Mode14的&#8220;伪帧&#8221;编码的，Mode14包含4bit的消息类型代码。表5.1列出了可用代码的说明和大小，发送给编/解码器的的消息大部分都可随意的被接受或被忽略。默认情况下，所有带内消息都被忽略掉了。</span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small"><img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none; border-image: initial" alt="In-band signalling codes" src="http://p.blog.csdn.net/images/p_blog_csdn_net/DotScylla/EntryImages/20090808/In-band%20signalling%20codes.jpg" width="663" height="367" /></span></span></span></p>
<p>&nbsp;</p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">表5.1&nbsp;带内信号代码</span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">Finally, applications may define custom in-band messages using mode 13. The size of the message in bytes is encoded with 5 bits, so that the decoder can skip it if it doesn&#8217;t know how to interpret it.</span></span></span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">最后，一些应用会使用Mode 13自定义带内消息，消息的字节大小是用5bits编码的，所以如果编码器不知道如何解析它就会跳过。</span></span></span></p>
<p>&nbsp;</p>
<p><strong><a style="color: rgb(51,102,153); text-decoration: none" name="Markup"></a><span style="font-size: large">补充：</span></strong></p>
<p><span style="font-size: small">本是第9章--Speex窄带模式中的图和表格，但本章中需要参考，贴上来</span></p>
<p><span style="font-size: small"><img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none; border-image: initial" alt="Analysis-by-synthesis closed-loop optimization on a sub-frame" src="http://p.blog.csdn.net/images/p_blog_csdn_net/DotScylla/EntryImages/20090808/Analysis-by-synthesis%20closed-loop%20optimization%20on%20a%20sub-frame.jpg" width="421" height="595" /></span></p>
<p><span style="font-size: small">Figure 9.2: Analysis-by-synthesis closed-loop optimization on a sub-frame.</span></p>
<p>&nbsp;</p>
<p><span style="font-size: small">&nbsp;<img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none; border-image: initial" alt="Quality versus bit rate" src="http://p.blog.csdn.net/images/p_blog_csdn_net/DotScylla/EntryImages/20090808/Quality%20versus%20bit%20rate.jpg" width="711" height="366" /></span></p>
<p><span style="font-size: small">Table 9.2: Quality versus bit-rate</span></p>
<p>&nbsp;</p>
<p><span style="font-size: small"><strong><a style="color: rgb(51,102,153); text-decoration: none" name="PostScript"></a><span style="font-size: large">后记</span>：</strong></span></p>
<p><span style="font-size: small">因为时间问题(英语学的太菜，翻译对偶来说是件困难的事情)，所以直接到第5章了，第3章--编译和移植和第4章--编/解码器命令行以后再进行翻译整理。</span></p>
<p><span style="font-family: 宋体"><span style="font-size: small"><a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/dotscylla/article/details/4426220#Packing&amp;In-band Signalling"></a></span></span></p>
<p>&nbsp;</p>
<p>&nbsp;</p></div><br /><br /><br /></div><img src ="http://www.cppblog.com/tx7do/aggbug/195513.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2012-11-22 00:03 <a href="http://www.cppblog.com/tx7do/archive/2012/11/22/195513.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Speex手册----编解码介绍</title><link>http://www.cppblog.com/tx7do/archive/2012/11/22/195512.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Wed, 21 Nov 2012 16:01:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2012/11/22/195512.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/195512.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2012/11/22/195512.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/195512.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/195512.html</trackback:ping><description><![CDATA[<div><strong>转载自:</strong><a href="http://blog.csdn.net/DotScylla/article/details/4402688"><strong>http://blog.csdn.net/DotScylla/article/details/4402688</strong></a>
<div style="border-bottom: rgb(204,204,204) 1px solid; min-width: 200px; text-align: left; border-left: rgb(204,204,204) 1px solid; padding-bottom: 4px; widows: 2; text-transform: none; background-color: rgb(238,238,238); text-indent: 0px; padding-left: 10px; padding-right: 10px; font: 12px Arial, Console, Verdana, 'Courier New'; white-space: normal; orphans: 2; float: left; letter-spacing: normal; color: rgb(51,51,51); border-top: rgb(204,204,204) 1px solid; border-right: rgb(204,204,204) 1px solid; word-spacing: 0px; padding-top: 4px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-origin: initial; background-clip: initial; border-image: initial">
<p style="text-align: right; margin: 0px"><span style="float: left"><strong>目录</strong><a style="color: rgb(51,102,153); text-decoration: none" title="系统根据文章中H1到H6标签自动生成文章目录" href="http://blog.csdn.net/DotScylla/article/details/4402688#"><strong>(?)</strong></a></span><a style="color: rgb(51,102,153); text-decoration: none" title="收起" onclick="javascript:return openct(this);" href="http://blog.csdn.net/DotScylla/article/details/4402688#"><strong>[-]</strong></a></p>
<ol style="line-height: 19px; padding-left: 14px; margin-left: 14px"><li><a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/DotScylla/article/details/4402688#t0"><strong>概念</strong></a></li><li><a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/DotScylla/article/details/4402688#t1"><strong>编解码</strong></a></li><li><a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/DotScylla/article/details/4402688#t2"><strong>预处理器</strong></a></li><li><a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/DotScylla/article/details/4402688#t3"><strong>自适应抖动缓冲</strong></a></li><li><a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/DotScylla/article/details/4402688#t4"><strong>回声消除</strong></a></li><li><a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/DotScylla/article/details/4402688#t5"><strong>重采样</strong></a></li></ol></div>
<div style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 12px Arial, Console, Verdana, 'Courier New'; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); clear: both; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"></div>
<div style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 20px 0px 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" id="article_content">
<div><span style="font-family: 宋体"><span style="font-family: 黑体"><span style="font-size: small">
<p><span style="font-family: 宋体"><strong>前言：</strong>Speex官网：<a style="color: rgb(51,102,153); text-decoration: none" href="http://speex.org/"><span style="color: rgb(51,102,153)"><span style="font-size: small">http://speex.org/</span></span></a><span style="font-size: small">&nbsp;可以再Documentation下找到PDF版或HTML OL版的英文手册。可能会由于英文技能的匮乏或语音解码领域的不熟悉会有翻译错误，所以每段我都会付上英文原段落，也望各位发现后能够不吝赐教，大家共同进步。</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体"><span style="font-size: small">PS:如需转载，注明出处，不胜感激</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体"><span style="font-size: small"><a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/DotScylla/article/details/4402688#conception">2.1 概念</a></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small">&nbsp;&nbsp;&nbsp;&nbsp;<a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/DotScylla/article/details/4402688#sampler">采样率</a></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small">&nbsp;&nbsp;&nbsp;&nbsp;<a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/DotScylla/article/details/4402688#bit-rate">比特率</a></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small">&nbsp;&nbsp;&nbsp;&nbsp;<a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/DotScylla/article/details/4402688#quality">质量(可变）</a></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small">&nbsp;&nbsp;&nbsp;&nbsp;<a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/DotScylla/article/details/4402688#complexity">复杂度(可变)</a></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small">&nbsp;&nbsp;&nbsp;&nbsp;<a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/DotScylla/article/details/4402688#variablebit-rate">变比特率</a></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small">&nbsp;&nbsp;&nbsp;&nbsp;<a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/DotScylla/article/details/4402688#averageBit-Rate">平均比特率</a></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small">&nbsp;&nbsp;&nbsp;&nbsp;<a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/DotScylla/article/details/4402688#VoiceActivity">静音检测</a></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small">&nbsp;&nbsp;&nbsp;&nbsp;<a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/DotScylla/article/details/4402688#Disconnection">非连续性传输</a></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small">&nbsp;&nbsp;&nbsp;&nbsp;<a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/DotScylla/article/details/4402688#Perceptual">知觉增强</a></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small">&nbsp;&nbsp;&nbsp;&nbsp;<a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/DotScylla/article/details/4402688#Algorithmic">延时算法</a></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small"><a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/DotScylla/article/details/4402688#Codec">2.2 编解码</a></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small"><a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/DotScylla/article/details/4402688#Preprocessor">2.3 预处理器</a></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small"><a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/DotScylla/article/details/4402688#JitterBuffer">2.4 自适应抖动缓冲</a></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small"><a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/DotScylla/article/details/4402688#EchoCanceller">2.5 回声消除</a></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small"><a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/DotScylla/article/details/4402688#Resampler">2.6 重采样</a></span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体"><span style="font-size: small"><a style="color: rgb(51,102,153); text-decoration: none" href="http://blog.csdn.net/DotScylla/article/details/4402688#PostScript">后记</a></span></span></p></span></span></span>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">This section describes Speex and its features into more details</span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif">这部分详细介绍Speex及其特性</span></span></p>
<h2><a style="color: rgb(51,102,153); text-decoration: none" name="t0"></a><span style="font-size: large"><span style="font-family: Arial"><a style="color: rgb(51,102,153); text-decoration: none" name="conception"></a>2.1&nbsp;</span><span style="font-family: 黑体">概念</span></span></h2>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif">Before introducing all the Speex features, here are some concepts in speech coding that help better understand the rest of the manual. Although some are general concepts in speech/audio processing, others are specific to Speex</span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif">在介绍Speex特性之前，为了便于阅读后面的文档，需要解释一些概念，尽管一些概念是在语音/音频处理过程中常见的，但也有Speex特有的一些。</span></span></p>
<p>&nbsp;</p>
<p><strong><span style="font-size: small"><span style="font-family: 宋体"><a style="color: rgb(51,102,153); text-decoration: none" name="sampler"></a>采样率</span></span></strong></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif">The sampling rate expressed in Hertz (Hz) is the number of samples taken from a signal per second. For a sampling rate of Fs kHz, the highest frequency that can be represented is equal to Fs/2 kHz (Fs/2 is known as the Nyquist frequency). This is a fundamental property in signal processing and is described by the sampling theorem. Speex is mainly designed for three different sampling rates: 8 kHz, 16 kHz, and 32 kHz. These are respectively refered to as narrowband, wideband and ultra-wideband.</span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">采样率是指从连续信号中每秒钟采集到的采样数量。用Fs kHz来表示，最高频率可表示为Fs/2 kHz（见奈奎斯特Nyquist频率）。采样定理表明这是信号处理最基本的属性。Speex主要设计了三种不同的采样率：8kHz，16kHz和32kHz。分别表示了窄带、宽带和超宽带。</span></span></span></p>
<p>&nbsp;</p><strong><span style="font-size: small"><span style="font-family: 宋体">
<p><a style="color: rgb(51,102,153); text-decoration: none" name="bit-rate"></a>比特率<span style="font-size: small">&nbsp;</span><strong>&nbsp;</strong></p></span></span></strong>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">When encoding a speech signal, the bit-rate is defined as the number of bits per unit of time required to encode the speech. It is measured in bits per second (bps), or generally kilobits per second. It is important to make the distinction between kilobits per second (kbps) and kilobytes per second (kBps).</span></span></p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">比特率是指每秒钟传送的比特数，在语音信号编码时，表示语音数据每秒钟需要多少个比特表示，单位为bps(比特/秒)或kbps(千比特/秒)。注意区分kbps和kBps（千字节/秒）。</span></span></p><strong>
<p>&nbsp;</p>
<p><span style="font-size: small"><span style="font-family: 宋体"><a style="color: rgb(51,102,153); text-decoration: none" name="quality"></a>质量</span><span style="font-family: 'Times New Roman'">(</span>可变<span style="font-family: 'Times New Roman'">)</span></span></p></strong>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif">Speex is a lossy codec, which means that it achives compression at the expense of fidelity of the input speech signal. Unlike ome other speech codecs, it is possible to control the tradeoff made between quality and bit-rate. The Speex encoding process is controlled most of the time by a quality parameter that ranges from 0 to 10. In constant bit-rate (CBR) operation, the quality parameter is an integer, while for variable bit-rate (VBR), the parameter is a float.</span></span></p>
<p><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">Speex是一种有损编解码库，这意味着它的文档压缩方面会导致语音输入信号的失真，和一些语音编解码库不同的是，它尽可能的去控制质量和比特率之间的平衡。大多数时候，是用一个0到10范围内的质量参数来控制Speex的编码，比特率为常量的操作，质量参数是整数，如果是变比特率（VBR），则为浮点数（Float）</span></span></p><strong>
<p>&nbsp;</p>
<p><span style="font-size: small"><span style="font-family: 宋体"><a style="color: rgb(51,102,153); text-decoration: none" name="complexity"></a>复杂度（可变）</span></span></p></strong>
<p><span style="font-size: small">With Speex, it is possible to vary the complexity allowed for the encoder. This is done by controlling how the search is performed with an integer ranging from 1 to 10 in a way that&#8217;s similar to the -1 to -9 options to gzip and bzip2 compression utilities. For normal use, the noise level at complexity 1 is between 1 and 2 dB higher than at complexity 10, but the CPU requirements for complexity 10 is about 5 times higher than for complexity 1. In practice, the best trade-off is between complexity 2 and 4, though higher settings are often useful when encoding non-speech sounds like DTMF tones.</span></p>
<p><span style="font-size: small">在Speex中，编码器可调整复杂度。用1到10的整数来控制如何执行搜索，就像用-1到-9来设置压缩工具gzip或bzip2(博主注：设计压缩的块长度,为100k～900k)。正常情况下，复杂度为1时噪声级会比复杂度为10时高1～2 dB(分贝)，而复杂度为10的CPU需求是复杂度为1的5倍。实践证明，最好将复杂度设置在2～4，设置较高则对非语音编码如双音多频（DTMF）音质较为有用。</span></p><strong>
<p>&nbsp;</p>
<p><span style="font-size: small"><span style="font-family: 宋体"><a style="color: rgb(51,102,153); text-decoration: none" name="variablebit-rate"></a>变比特率（</span><span style="font-family: 'Times New Roman'">VBR</span>）</span></p></strong>
<p><span style="font-size: small">Variable bit-rate (VBR) allows a codec to change its bit-rate dynamically to adapt to the &#8220;difficulty&#8221; of the audio being encoded. In the example of Speex, sounds like vowels and high-energy transients require a higher bit-rate to achieve good quality, while fricatives (e.g. s,f sounds) can be coded adequately with less bits. For this reason, VBR can achive lower bit-rate for the same quality, or a better quality for a certain bit-rate. Despite its advantages, VBR has two main drawbacks: first, by only specifying quality, there&#8217;s no guaranty about the final average bit-rate. Second, for some real-time applications like voice over IP (VoIP), what counts is the maximum bit-rate, which must be low enough for the communication channel.</span></p>
<p><span style="font-size: small">变比牲率（VBR）允许编解码器动态调整比特率以适应的音频解码的&#8220;难度&#8221;，拿Speex来说，像元音和瞬间高音则需较高比特率（Bit-rate）来达到最佳效果，而摩擦音则用较少的比特（bits）即可完成编码。基于这种原因，变比特率（VBR）可以用较低的比特率(bit-rate)达到相同的效果或使用某比特率（bit-rate）质量会更好。尽管它有这些优势，但VBR也有两个主要的缺点：首先，它只是针对质量，却没办法保证最终的平均比特率（ABR）; 其次，在一些实时应用如VOIP电话中，尽管拥有高的比特率（bit-rate），为适应通信信道还是需要适当降低。</span></p><strong>
<p>&nbsp;</p>
<p><span style="font-size: small"><span style="font-family: 宋体"><a style="color: rgb(51,102,153); text-decoration: none" name="averageBit-Rate"></a>平均比特率（</span><span style="font-family: 'Times New Roman'">ABR</span>）</span></p></strong>
<p><span style="font-size: small">Average bit-rate solves one of the problems of VBR, as it dynamically adjusts VBR quality in order to meet a specific target bit-rate. Because the quality/bit-rate is adjusted in real-time (open-loop), the global quality will be slightly lower than that obtained by encoding in VBR with exactly the right quality setting to meet the target average bit-rate.</span></p>
<p><span style="font-size: small">平均比特率（ABR）通过动态调整变比特率(VBR)的质量来获得一个特定目标的比特率，解决了VBR中存在的问题之一。因为平均比特率（ABR）是实时（开环）调整质量/比特率(bit-rate)的，整体质量会略低于通过变比特率（VBR）设置的接近于目标平均比特率进行编码获得的质量。</span></p><strong>
<p>&nbsp;</p>
<p><span style="font-size: small"><span style="font-family: 宋体"><a style="color: rgb(51,102,153); text-decoration: none" name="VoiceActivity"></a>静音检测（</span><span style="font-family: 'Times New Roman'">VAD</span>）</span></p></strong>
<p><span style="font-size: small">When enabled, voice activity detection detects whether the audio being encoded is speech or silence/background noise. VAD is always implicitly activated when encoding in VBR, so the option is only useful in non-VBR operation. In this case, Speex detects non-speech periods and encode them with just enough bits to reproduce the background noise. This is called &#8220;comfort noise generation&#8221; (CNG).</span></p>
<p><span style="font-size: small">静音检测（VAD）将检测被编码的音频数据是语音还是静音或背景噪声。这个特性在用变比特率（VBR）进行编码是总是开启的，所以选项设置只对非变比特率（VBR）起作用。在这种情况下，Speex检测非语音周期并对用足够的比特数重新生成的背景噪声进行编码。这个叫&#8220;舒适噪声生成（CNG）&#8221;。</span></p><strong>
<p>&nbsp;</p>
<p><span style="font-size: small"><span style="font-family: 宋体"><a style="color: rgb(51,102,153); text-decoration: none" name="Disconnection"></a>非连续传输（</span><span style="font-family: 'Times New Roman'">DTX</span>）</span></p></strong>
<p><span style="font-size: small">Discontinuous transmission is an addition to VAD/VBR operation, that allows to stop transmitting completely when the background noise is stationary. In file-based operation, since we cannot just stop writing to the file, only 5 bits are used for such frames (corresponding to 250 bps).</span></p>
<p><span style="font-size: small">非连续性传输（DTX）是静音检测（VAD）/变比特率（VBR）操作的额外选项，它能够在背景噪声固定时，完全的停止传输。如果是基于文件的操作，由于我们不能停止对文件的写入，会有5个比特被用到这种帧内（相对于250bps）。</span></p><strong>
<p>&nbsp;</p>
<p><span style="font-size: small"><span style="font-family: 宋体"><a style="color: rgb(51,102,153); text-decoration: none" name="Perceptual"></a>知觉增强</span></span></p></strong>
<p><span style="font-size: small">Perceptual enhancement is a part of the decoder which, when turned on, attempts to reduce the perception of the noise/distortion produced by the encoding/decoding process. In most cases, perceptual enhancement brings the sound further from the original objectively (e.g. considering only SNR), but in the end it still sounds better (subjective improvement).</span></p>
<p><span style="font-size: small">知觉增强中解码的一部分，开启后，用来减少在编码/解码过程中产生的噪音/失真。大多数情况下，知觉增强产生的会和最原始的声音会相差较远（如只考虑信噪比（SNR）），但最后发音效果却很好（主观改善）。</span></p><strong>
<p>&nbsp;</p>
<p><span style="font-size: small"><span style="font-family: 宋体"><a style="color: rgb(51,102,153); text-decoration: none" name="Algorithmic"></a>延时算法</span></span></p></strong>
<p><span style="font-size: small">Every speech codec introduces a delay in the transmission. For Speex, this delay is equal to the frame size, plus some amount of &#8220;look-ahead&#8221; required to process each frame. In narrowband operation (8 kHz), the delay is 30 ms, while for wideband (16 kHz), the delay is 34 ms. These values don&#8217;t account for the CPU time it takes to encode or decode the frames.</span></p>
<p><span style="font-size: small">每个声音编解码在传输过程中都会有时延。就Speex来说，它的时延就等于每帧大小加上每帧需要处理的一些"预测"(look-ahead)。在窄带(8kHz)操作中,大概30ms时延，宽带操作大概34ms时延。而且没有将CPU进行编/解码的时间计算在内。</span></p><strong>
<h2><a style="color: rgb(51,102,153); text-decoration: none" name="t1"></a><span style="font-size: large"><span style="font-family: Arial"><a style="color: rgb(51,102,153); text-decoration: none" name="Codec"></a>2.2&nbsp;</span><span style="font-family: 黑体">编解码</span></span></h2></strong>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif">The main characteristics of Speex can be summarized as follows:<br />&nbsp;&nbsp;&nbsp; &#8226; Free software/open-source, patent and royalty-free<br />&nbsp;&nbsp;&nbsp; &#8226;&nbsp;Integration of narrowband and wideband using an embedded bit-stream<br />&nbsp;&nbsp;&nbsp; &#8226; Wide range of bit-rates available (from 2.15 kbps to 44 kbps)<br />&nbsp;&nbsp;&nbsp; &#8226; Dynamic bit-rate switching (AMR) and Variable Bit-Rate (VBR) operation<br />&nbsp;&nbsp;&nbsp; &#8226; Voice Activity Detection (VAD, integrated with VBR) and discontinuous transmission (DTX)<br />&nbsp;&nbsp;&nbsp; &#8226; Variable complexity<br />&nbsp;&nbsp;&nbsp; &#8226; Embedded wideband structure (scalable sampling rate)<br />&nbsp;&nbsp;&nbsp; &#8226; Ultra-wideband sampling rate at 32 kHz<br />&nbsp;&nbsp;&nbsp; &#8226; Intensity stereo encoding option<br />&nbsp;&nbsp;&nbsp; &#8226; Fixed-point implementation</span></span></p>
<p><span style="font-size: small"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">Speex的主要特性总结如下：</span></span></span></p>
<ul><li>
<div style="text-indent: -21pt; margin: 0cm 0cm 0pt 21pt"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">开源的自由软件，免专利，免版权</span></span></div></li><li>
<div style="text-indent: -21pt; margin: 0cm 0cm 0pt 21pt"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">通过嵌入的比特流集成窄带和宽带</span></span></div></li><li>
<div style="text-indent: -21pt; margin: 0cm 0cm 0pt 21pt"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">可大范围改变比特率（bit-rate）（从2.15kbps到44kbps ）</span></span></div></li><li>
<div style="text-indent: -21pt; margin: 0cm 0cm 0pt 21pt"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">动态比特率交换（AMR）和变比特率（VBR）操作</span></span></div></li><li>
<div style="text-indent: -21pt; margin: 0cm 0cm 0pt 21pt"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">静音检测（VAD，和变比特率（VBR）集成）和非连续性传输（DTX）</span></span></div></li><li>
<div style="text-indent: -21pt; margin: 0cm 0cm 0pt 21pt"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">可变复杂度</span></span></div></li><li>
<div style="text-indent: -21pt; margin: 0cm 0cm 0pt 21pt"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">嵌入的宽带结构（可变的比特率）</span></span></div></li><li>
<div style="text-indent: -21pt; margin: 0cm 0cm 0pt 21pt"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">32kHz的超宽带采样率</span></span></div></li><li>
<div style="text-indent: -21pt; margin: 0cm 0cm 0pt 21pt"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">强立体声编码选项</span></span></div></li><li>
<div style="text-indent: -21pt; margin: 0cm 0cm 0pt 21pt"><span style="font-family: arial, helvetica, sans-serif"><span style="font-size: small">定点执行</span></span></div></li></ul><strong><span style="font-size: large"><span style="font-family: Arial">
<h2><a style="color: rgb(51,102,153); text-decoration: none" name="t2"></a><a style="color: rgb(51,102,153); text-decoration: none" name="Preprocessor"></a><span style="font-family: 黑体"><span style="font-size: large"><span style="font-family: Arial">2.3&nbsp;</span>预处理器</span></span></h2></span></span></strong>
<p><span style="font-size: small">This part refers to the preprocessor module introduced in the 1.1.x branch. The preprocessor is designed to be used on the<br />audio before running the encoder. The preprocessor provides three main functionalities:<br />&#8226; noise suppression<br />&#8226; automatic gain control (AGC)<br />&#8226; voice activity detection (VAD)</span></p>
<p><span style="font-size: small">这部分涉及到1.1.x里的预处理模块介绍，预处理器是在音频被编码前使用，它主要提供如下三种主要功能：</span></p>
<ul><li>
<div style="text-indent: -21pt; margin: 0cm 0cm 0pt 21pt"><span style="font-size: small">抑制噪音</span></div></li><li>
<div style="text-indent: -21pt; margin: 0cm 0cm 0pt 21pt"><span style="font-size: small">自动增益控制（AGC）</span></div></li><li>
<div style="text-indent: -21pt; margin: 0cm 0cm 0pt 21pt"><span style="font-size: small">静音检测（VAD）</span></div></li></ul>
<p>&nbsp;</p>
<p><span style="font-size: small">The denoiser can be used to reduce the amount of background noise present in the input signal. This provides higher quality speech whether or not the denoised signal is encoded with Speex (or at all). However, when using the denoised signal with the codec, there is an additional benefit. Speech codecs in general (Speex included) tend to perform poorly on noisy input, which tends to amplify the noise. The denoiser greatly reduces this effect.</span></p>
<p><span style="font-size: small">降噪是用来减少输入信号中的背景噪音的数量。不论是Speex（或其他）编码的去噪信号可提供更高的语音质量。无论如何编解码器使用降噪信号都是有利的。一般的语音编解码器（Speex中也包含）在噪音输入方面都表现不佳，往往会扩大噪音。而降噪则大大降低了这种影响。</span></p>
<p>&nbsp;</p>
<p><span style="font-size: small">Automatic gain control (AGC) is a feature that deals with the fact that the recording volume may vary by a large amount between different setups. The AGC provides a way to adjust a signal to a reference volume. This is useful for voice over IP because it removes the need for manual adjustment of the microphone gain. A secondary advantage is that by setting the microphone gain to a conservative (low) level, it is easier to avoid clipping.</span></p>
<p><span style="font-size: small">不同的设备，录音效果会有较大幅度的变动，自动增益控制（AGC）就是用来处理这种现象的。它提供了一种调整信号为参考音量的方法。这对VOIP（voice over IP）是非常有用的，因为它不需要再手动去调整麦克风增益。第二个好处是，将麦克风增益设置为保守(低)级别，可有效避免削波。</span></p>
<p>&nbsp;</p>
<p><span style="font-size: small">The voice activity detector (VAD) provided by the preprocessor is more advanced than the one directly provided in the codec.</span></p>
<p><span style="font-size: small">预处理器提供的静音检测（VAD）比编解码器里直接提供的更为先进。</span></p>
<h2><a style="color: rgb(51,102,153); text-decoration: none" name="t3"></a><span style="font-size: large"><span style="font-family: Arial"><a style="color: rgb(51,102,153); text-decoration: none" name="JitterBuffer"></a>2.4&nbsp;</span><span style="font-family: 黑体">自适应抖动缓冲</span></span></h2>
<p><span style="font-size: small">When transmitting voice (or any content for that matter) over UDP or RTP, packet may be lost, arrive with different delay,or even out of order. The purpose of a jitter buffer is to reorder packets and buffer them long enough (but no longer than necessary) so they can be sent to be decoded.</span></p>
<p><span style="font-size: small">在用UDP或RTP协议传输语音（或其他相关内容）的时候，会出现丢包、不同时延甚至是非时序的到达。抖动缓冲的目的就是将它们缓冲到足够长（不超过必需的）并对这些包进行重排序，然后才送给解码器进行解码。</span></p>
<h2><a style="color: rgb(51,102,153); text-decoration: none" name="t4"></a><span style="font-size: large"><span style="font-family: Arial"><a style="color: rgb(51,102,153); text-decoration: none" name="EchoCanceller"></a>2.5&nbsp;</span><span style="font-family: 黑体">回声消除</span></span></h2>
<p align="center"><strong>&nbsp;</strong></p>
<p><strong><span style="font-size: small"><span style="font-family: 宋体"><img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none; border-image: initial" alt="Acoustic Echo Model" src="http://p.blog.csdn.net/images/p_blog_csdn_net/DotScylla/EntryImages/20090803/EchoCanceller.JPG" width="516" height="271" /></span></span></strong></p>
<p><span style="font-size: small">图 2.1 回声模式</span></p>
<p><span style="font-size: small">In any hands-free communication system (Fig. 2.1), speech from the remote end is played in the local loudspeaker, propagates in the room and is captured by the microphone. If the audio captured from the microphone is sent directly to the remote end, then the remove user hears an echo of his voice. An acoustic echo canceller is designed to remove the acoustic echo before it is sent to the remote end. It is important to understand that the echo canceller is meant to improve the quality on the remote end.</span></p>
<p><span style="font-size: small">如图2.1所示，在免提通信系统中，语音从远端传回本地的扩音器，麦克风回捕获房内的回声，然后会将其直接发回给远端，远端用户就会听到它自己的声音。回声消除器就是为了在回声传回给远端用户之前将其消除。重要的是要明白，回声消除用来提高远端用户接收到的语音质量。</span></p>
<h2><a style="color: rgb(51,102,153); text-decoration: none" name="t5"></a><span style="font-size: large"><span style="font-family: Arial"><a style="color: rgb(51,102,153); text-decoration: none" name="Resampler"></a>2.6&nbsp;</span><span style="font-family: 黑体">重采样</span></span></h2>
<p><span style="font-size: small">In some cases, it may be useful to convert audio from one sampling rate to another. There are many reasons for that. It can be for mixing streams that have different sampling rates, for supporting sampling rates that the soundcard doesn&#8217;t support, for transcoding, etc. That&#8217;s why there is now a resampler that is part of the Speex project. This resampler can be used to convert between any two arbitrary rates (the ratio must only be a rational number) and there is control over the quality/complexity tradeoff.</span></p>
<p><span style="font-size: small">在一些情况下，改变音频的采样率是非常有用的。有很多原因，如拥有不同采样率则可进行混合流、支持声卡不支持的采样率、代码转换等。这是为什么重采样会成为Speex工程的一部分。重采样可在任意比率之间转换（比率必须是有理数），它是基于质量/复杂度进行的折中。&nbsp;</span></p>
<p><strong>&nbsp;</strong></p>
<p><span style="font-family: 宋体; font-size: 10.5pt"><a style="color: rgb(51,102,153); text-decoration: none" name="PostScript"></a><span style="font-size: small"><strong>后记：</strong></span></span></p>
<p>&nbsp;<span style="font-size: small">嗯，总体来说感觉翻译的蛮粗糙的，有些地方理解的不是很透，放在这里供大家拍砖。</span></p></div></div><br /><br /><br /><br /><br /><br /><br /></div><img src ="http://www.cppblog.com/tx7do/aggbug/195512.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2012-11-22 00:01 <a href="http://www.cppblog.com/tx7do/archive/2012/11/22/195512.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Speex手册----Speex 简介</title><link>http://www.cppblog.com/tx7do/archive/2012/11/21/195511.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Wed, 21 Nov 2012 15:59:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2012/11/21/195511.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/195511.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2012/11/21/195511.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/195511.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/195511.html</trackback:ping><description><![CDATA[<div><strong style="color: red">转载自:</strong><a style="color: red" href="http://www.cnblogs.com/rosesmall/archive/2012/04/18/2455385.html"><strong>http://www.cnblogs.com/rosesmall/archive/2012/04/18/2455385.html</strong></a><br /><br />
<div style="widows: 2; text-transform: none; text-indent: 0px; font: 13px/19px Verdana, Geneva, Arial, Helvetica, sans-serif; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(0,0,0); word-break: normal !important; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" id="cnblogs_post_body">
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">&nbsp;前言：没搜到Speex相关的中文资料，所以想将Speex的英文手册中会用到的部分翻译出来。Speex官网：<a style="background-color: transparent; color: rgb(51,102,153); text-decoration: none; background-origin: initial; background-clip: initial" href="http://speex.org/">http://speex.org/</a>&nbsp;可以再Documentation下找到PDF版或HTML OL版的英文手册。每段我都会付上英文原段落，可能会由于英文技能的匮乏或语音解码领域的不熟悉会有翻译错误，也望各位发现后能够不吝赐教，大家共同进步。</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">PS:如需转载，注明出处，不胜感激</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">&nbsp;</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">简介</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">1.1 获得帮助</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">1.2 关于此文档</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">后记</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">&nbsp;</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">简介：</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">The Speex codec (<a style="background-color: transparent; color: rgb(51,102,153); text-decoration: none; background-origin: initial; background-clip: initial" href="http://www.speex.org/">http://www.speex.org/</a>) exists because there is a need for a speech codec that is open-source and free from software patent royalties. These are essential conditions for being usable in any open-source software. In essence,Speex is to speech what Vorbis is to audio/music. Unlike many other speech codecs, Speex is not designed for mobile phones but rather for packet networks and voice over IP (VoIP) applications. File-based compression is of course also supported.</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">由于语音对话编解码需要一个免费的开源软件，所以诞生了Speex库，可以在任何开源软件中使用。实际上，Speex对于语音对话来讲，相当于Vorbis[一种可将声音来源加以压缩的编码软件，开放源码且免版权]对于音频/音乐。和大多数语音编解码库不一样的是，Speex不是为移动电话而设计的，而是为分组网络的VOIP(Voice over IP)应用程序，同时支持基于文件的压缩。</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">&nbsp;</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">The Speex codec is designed to be very flexible and support a wide range of speech quality and bit-rate. Support for very good quality speech also means that Speex can encode wideband speech (16 kHz sampling rate) in addition to narrowband speech (telephone quality, 8 kHz sampling rate).</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Speex编解码库的设计非常灵活，支持广泛的语音质量和比特率。良好的语音质量支持意味着除了窄带语音( 电话质量，8kHz采样率)外还可以对宽带语音( 电话质量，16kHz采样率)进行编解码。</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">&nbsp;</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">&nbsp;&nbsp;&nbsp; Designing for VoIP instead of mobile phones means that Speex is robust to lost packets, but not to corrupted ones. This is based on the assumption that in VoIP, packets either arrive unaltered or don&#8217;t arrive at all. Because Speex is targeted at a wide range of devices, it has modest (adjustable) complexity and a small memory footprint.</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Speex被设计用于VoIP而不是移动电话，意味着Speex对于丢包能够妥善处理,不会有损坏数据。这在VOIP里是基于这样的假设，数据包要么不被改变的到达，要么不会到达。Speex针对于大多数的设备，因此它拥有适中（可调整）的复杂性和较小内存占用。</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">&nbsp;</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">&nbsp;&nbsp; All the design goals led to the choice of CELP as the encoding technique. One of the main reasons is that CELP has long proved that it could work reliably and scale well to both low bit-rates (e.g. DoD CELP @ 4.8 kbps) and high bit-rates (e.g.G.728 @ 16 kbps).</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 所有这些设计的目的是为了引入码激励线性预测(CELP)编码技术，因为长期实践表明它对于低比特率（如DoD CELP@ 4.8kbps）和高比特率（如G.728 @ 16kbps）的工作性能良好,可靠性高。</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">1.1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 获得帮助<br />As for many open source projects, there are many ways to get help with Speex. These include:<br />&#8226; This manual<br />&#8226; Other documentation on the Speex website (<a style="background-color: transparent; color: rgb(51,102,153); text-decoration: none; background-origin: initial; background-clip: initial" href="http://www.speex.org/">http://www.speex.org/</a>)<br />&#8226; Mailing list: Discuss any Speex-related topic on&nbsp;<a style="background-color: transparent; color: rgb(51,102,153); text-decoration: none; background-origin: initial; background-clip: initial" href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#115;&#112;&#101;&#101;&#120;&#45;&#100;&#101;&#118;&#64;&#120;&#105;&#112;&#104;&#46;&#111;&#114;&#103;">speex-dev@xiph.org</a>&nbsp;(not just for developers)<br />&#8226; IRC: The main channel is #speex on irc.freenode.net. Note that due to time differences, it may take a while to get someone, so please be patient.<br />&#8226; Email the author privately at&nbsp;<a style="background-color: transparent; color: rgb(51,102,153); text-decoration: none; background-origin: initial; background-clip: initial" href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#106;&#101;&#97;&#110;&#45;&#109;&#97;&#114;&#99;&#46;&#118;&#97;&#108;&#105;&#110;&#64;&#117;&#115;&#104;&#101;&#114;&#98;&#114;&#111;&#111;&#107;&#101;&#46;&#99;&#97;">jean-marc.valin@usherbrooke.ca</a>&nbsp;only for private/delicate topics you do not wish to discuss publically.</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">类似于大多数开源项目，Speex也可以能过多种获得帮助的路径，包括：</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 本手册</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Speex官方站点（<a style="background-color: transparent; color: rgb(51,102,153); text-decoration: none; background-origin: initial; background-clip: initial" href="http://www.speex.org/">http://www.speex.org/</a>&nbsp;）的其他文档</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 邮件列表：讨论Speex相关发送至&nbsp;<a style="background-color: transparent; color: rgb(51,102,153); text-decoration: none; background-origin: initial; background-clip: initial" href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#115;&#112;&#101;&#101;&#120;&#45;&#100;&#101;&#118;&#64;&#120;&#105;&#112;&#104;&#46;&#111;&#114;&#103;">speex-dev@xiph.org</a>&nbsp;(不是仅限于开发者)</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IRC：通过irc.freenode.net Speex频道获取，可能需要耐心等待一段时间</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果不想公开讨论一些主题，可Email作者<a style="background-color: transparent; color: rgb(51,102,153); text-decoration: none; background-origin: initial; background-clip: initial" href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#106;&#101;&#97;&#110;&#45;&#109;&#97;&#114;&#99;&#46;&#118;&#97;&#108;&#105;&#110;&#64;&#117;&#115;&#104;&#101;&#114;&#98;&#114;&#111;&#111;&#107;&#101;&#46;&#99;&#97;">jean-marc.valin@usherbrooke.ca</a></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">&nbsp;</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">Before asking for help (mailing list or IRC), it is important to first read this manual (OK, so if you made it here it&#8217;s already a good sign). It is generally considered rude to ask on a mailing list about topics that are clearly detailed in the documentation. On the other hand, it&#8217;s perfectly OK (and encouraged) to ask for clarifications about something covered in the manual. This manual does not (yet) cover everything about Speex, so everyone is encouraged to ask questions, send comments, feature requests, or just let us know how Speex is being used.</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">在寻求帮助前（邮件列表或IRC），最好先仔细阅读本手册（呵呵，看到这里说明你已经有一个不错的开始），如果文档中介绍的很详细的问题你仍然去Email多不好。当然，本手册也不可能囊括关于Speex所有的知识点，所以也希望大家多提问题和见解、以及需要改进或增加的功能，或者是仅仅让我们知道您在使用Speex。</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">&nbsp;</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">Here are some additional guidelines related to the mailing list. Before reporting bugs in Speex to the list, it is strongly recommended (if possible) to first test whether these bugs can be reproduced using the speexenc and speexdec (see Section 4)<br />command-line utilities. Bugs reported based on 3rd party code are both harder to find and far too often caused by errors that have nothing to do with Speex.</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">在发送报告Bugs的邮件时，也对大家有些额外的要求，建议（如果可能）先使用Speexenc和Speexdec（见第4节）命令行工具测试能否使Bugs再现，很多报告的Bug都由第三方的代码引起而难以发现，造成的错误往往不关Speex的事。</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">1.2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 关于此文档<br />This document is divided in the following way. Section 2 describes the different Speex features and defines many basic terms that are used throughout this manual. Section 4 documents the standard command-line tools provided in the Speex distribution. Section 5 includes detailed instructions about programming using the libspeex API. Section 7 has some information related to Speex and standards.</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">文档分为几部分，第2节介绍Speex的特性以及一些文档中用到的基本术语。第4节是关于Speex提供的标准命令行工具。第5节是使用libspeex API进行编程的详细说明。第7节是一些关于Speex相关标准的信息。</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">&nbsp;</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">&nbsp;&nbsp;&nbsp; The three last sections describe the algorithms used in Speex. These sections require signal processing knowledge, but are not required for merely using Speex. They are intended for people who want to understand how Speex really works and/or want to do research based on Speex. Section 8 explains the general idea behind CELP, while sections 9 and 10 are specific to Speex.</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">&nbsp;&nbsp;&nbsp; 最后三节介绍了Speex使用的算法。这部分需要信号处理相关知识，但这是对于那些想了解Speex的真正工作原理或基于Speex进行研究的人，如果仅仅是使用Speex库则不是必需的。第8节大概介绍了CELP（码激励线性预测）编码，9和10节是关于Speex的一些具体介绍。</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">后记：</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">如果哪位同学已拥有此手册的中文版本，可留我一份，不然偶得继续增强英文了，也不算一件坏事。</p></div></div><img src ="http://www.cppblog.com/tx7do/aggbug/195511.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2012-11-21 23:59 <a href="http://www.cppblog.com/tx7do/archive/2012/11/21/195511.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Speex manul中文版</title><link>http://www.cppblog.com/tx7do/archive/2012/11/21/195510.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Wed, 21 Nov 2012 15:56:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2012/11/21/195510.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/195510.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2012/11/21/195510.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/195510.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/195510.html</trackback:ping><description><![CDATA[<strong style="color: red">转载自:</strong><a style="color: red" href="http://www.cnblogs.com/rosesmall/archive/2012/04/18/2455395.html"><strong>http://www.cnblogs.com/rosesmall/archive/2012/04/18/2455395.html</strong></a><br /><br />
<div style="widows: 2; text-transform: none; text-indent: 0px; font: 13px/19px Verdana, Geneva, Arial, Helvetica, sans-serif; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(0,0,0); word-break: normal !important; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" id="cnblogs_post_body">
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px"><span lang="EN-US"><span><strong>在VOIP的音频算法中，回音处理已经成为一个关系通话质量的主要问题。</strong></span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px"><span lang="EN-US"><span><strong>回声的产生在IP网络主要有两种：<br />1.声学回声<br />2.电路回声</strong></span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px"><span lang="EN-US"><span><strong>声学回声主要又分成以下几种:<br />a ) 直接回声:由扬声器产生的声音未经任何反射直接进入麦克风<br />b ) 间接回声: 由扬声器发出的声音经过多次反射后,再进入Mic<br />对于第二种回声,拥有多路径,时变性的特点.是比较难处理的.</strong></span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px"><span lang="EN-US"><span><strong>由于IP网络下的传输的延迟较大,而一般情况下,对于人耳,如果声音延迟达到了10ms以上的话,那么回声就会越来越明显.<br />一般来讲,VOIP中的声音延迟主要来自于几个方面:<br />1. 编码延迟: 一般情况下编码算法在声音压缩时都会产生延迟,就我们采用的Speex来讲,延迟大概在20ms左右<br />2. 处理延迟, 封装时延, 缓冲时延等<br />3. 在IP网络中数据的传输过程也会照成延时.这由当前的网络状况决定.</strong></span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px"><span lang="EN-US"><span><strong>回声消除的模型:<br />a) 建立远端声音模型,进行回声估计, 从采集的值中减去估计值<br />b) 声学模型</strong></span></span></p>
<h4 id="subjcns!31B2F8637FF39314!234" class="TextColor1"><span>Speex manul(手册)中文版</span></h4>
<div id="msgcns!31B2F8637FF39314!234">
<div>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px"><span lang="EN-US"><span>Speex</span></span><span>是一套专门用于压缩声音的库</span><span lang="EN-US"><span>,</span></span><span>由于其专门针对声音</span><span lang="EN-US"><span>,</span></span><span>所以压缩声音的性能非常高</span><span lang="EN-US"><span>.Speex</span></span><span>由于其压缩性能</span><span lang="EN-US"><span>,</span></span><span>及</span><span lang="EN-US"><span>0.80</span></span><span>版后的跨平台的性能</span><span lang="EN-US"><span>,</span></span><span>所以在网络声音的传输中有很大的价值</span><span lang="EN-US"><span>.</span></span><span>但是需要注意的是</span><span lang="EN-US"><span>speex</span></span><span>只能对声音进行压缩</span><span lang="EN-US"><span>,</span></span><span>不支持音乐的压缩</span><span lang="EN-US"><span>,</span></span><span>如果你需要音乐的压缩你或许需要用</span><span lang="EN-US"><span>vorbis</span></span><span>库</span><span lang="EN-US"><span>.</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span><span>但是的</span><span lang="EN-US"><span>speex</span></span><span>资料像其它大都数专用库一样</span><span lang="EN-US"><span>,</span></span><span>并没有大多的中文资料</span><span lang="EN-US"><span>.</span></span><span>所以在这里我决定将里面最核心的编程技术翻译出来</span><span lang="EN-US"><span>.</span></span><span>一来是练习练习自己翻译资料的能力</span><span lang="EN-US"><span>,</span></span><span>二来是方便一些英语水平较差的朋友</span><span lang="EN-US"><span>.</span></span><span>由于本人能力有限</span><span lang="EN-US"><span>,</span></span><span>有些感觉有出入或难理解的地方可以去</span><span lang="EN-US"><span>speex</span></span><span>的官方网站</span><span lang="EN-US"><a style="background-color: transparent; color: rgb(51,102,153); text-decoration: none; background-origin: initial; background-clip: initial" href="http://www.speex.org/"><span>www.speex.org</span></a></span><span>找到英文原版的说明</span><span lang="EN-US"><span>.</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px"><span>翻译的一些说明</span><span lang="EN-US"><span>:</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px"><span lang="EN-US"><span>1,</span></span><span>对于一些专有名词如</span><span lang="EN-US"><span>speex,api</span></span><span>不过行翻译</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px"><span lang="EN-US"><span>2,</span></span><span>对于一些新概念翻译</span><span lang="EN-US"><span>,</span></span><span>以及其它的翻译过来也许会产生歧义的文字</span><span lang="EN-US"><span>,</span></span><span>用中</span><span lang="EN-US"><span>/</span></span><span>英两种方式标出</span><span lang="EN-US"><span>:</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span><span>如</span><span lang="EN-US"><span>:</span></span><span>对话</span><span lang="EN-US"><span>(speech),</span></span><span>位采集</span><span lang="EN-US"><span>(bit_packing)</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px"><span lang="EN-US"><span>3,</span></span><span>基本做到和英文原行对译</span><span lang="EN-US"><span>.</span></span><span>及英文原文一行</span><span lang="EN-US"><span>,</span></span><span>中文翻译过来也是一行</span><span lang="EN-US"><span>,</span></span><span>使翻译后的文章和原文基本行行对照</span><span lang="EN-US"><span>.</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px"><span lang="EN-US"><span>4,</span></span><span>源代码不翻译</span><span lang="EN-US"><span>,</span></span><span>如</span><span lang="EN-US"><span>SpeexBits bits;</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px"><span lang="EN-US"><span>5,</span></span><span>语言中的关健字不译</span><span lang="EN-US"><span>,</span></span><span>如</span><span lang="EN-US"><span>float</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px"><span lang="EN-US"><span>6,</span></span><span>一此不是关健字但英文通常出现的词第一次以中</span><span lang="EN-US"><span>/</span></span><span>英文格式给出</span><span lang="EN-US"><span>,</span></span><span>之后按具体情况给出英文或中文</span><span lang="EN-US"><span>,</span></span><span>如</span><span lang="EN-US"><span>:frame(</span></span><span>帧</span><span lang="EN-US"><span>),</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px"><span lang="EN-US"><span>7,</span></span><span>对一些有自己翻译起来感觉有歧义的地方</span><span lang="EN-US"><span>,</span></span><span>加斜线作标记</span>&nbsp;</p></div></div>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span><strong>1,speex的介绍(略)</strong></span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span><strong><span>2</span>特征描述</strong></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>这个章节展示了</span><span lang="EN-US"><span>speex</span></span><span>的主要特征</span><span lang="EN-US"><span>,</span></span><span>以衣一些关于对话</span><span lang="EN-US"><span>(speech)</span></span><span>编码的一个概念</span><span lang="EN-US"><span>,</span></span><span>以便</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>帮助我们更好的了解下一章节</span><span lang="EN-US"><span>.</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span><strong>取样率<span>(Sampling rate)</span></strong></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>Speex</span></span><span>主要是设计了三种不同的取样率</span><span lang="EN-US"><span>:8kHz,16kHz,32kHz.</span></span><span>这些分别代表了窄宽</span><span lang="EN-US"><span>(narrowband),</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>多频率</span><span lang="EN-US"><span>,</span></span><span>超声</span><span lang="EN-US"><span>.</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span><strong>质量</strong></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>Speex</span></span><span>编码大都数时间是被一个范围为</span><span lang="EN-US"><span>0</span></span><span>到</span><span lang="EN-US"><span>10</span></span><span>的质量参数来控制</span><span lang="EN-US"><span>&nbsp;&nbsp;</span></span><span>的</span><span lang="EN-US"><span>.</span></span><span>在一个比特率为常量</span><span lang="EN-US"><span>(CBR)</span></span><span>的操作中</span><span lang="EN-US"><span>,</span></span><span>质量参数是一个整数</span><span lang="EN-US"><span>,</span></span><span>而对于变动的比特率</span><span lang="EN-US"><span>(VBR)</span></span><span>参数是一个</span><span lang="EN-US"><span>float;</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span><strong><span>复杂性</span><span lang="EN-US"><span>(</span></span><span>变量</span><span lang="EN-US"><span>)</span></span></strong></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>用</span><span lang="EN-US"><span>speex,</span></span><span>你可以将编码设置成允许的复杂度</span><span lang="EN-US"><span>.</span></span><span>这由一个范围为</span><span lang="EN-US"><span>1</span></span><span>到</span><span lang="EN-US"><span>10</span></span><span>的整数来控制完成</span><span lang="EN-US"><span>,</span></span><span>就像你用选项</span><span lang="EN-US"><span>-1</span></span><span>到</span><span lang="EN-US"><span>-9</span></span><span>来控制</span><span lang="EN-US"><span>gzip</span></span><span>和</span><span lang="EN-US"><span>bzip2</span></span><span>的压缩质量</span><span lang="EN-US"><span>.</span></span><span>在通常的运用中</span><span lang="EN-US"><span>,</span></span><span>噪声级别的复杂度</span><span lang="EN-US"><span>1</span></span><span>是在</span><span lang="EN-US"><span>1</span></span><span>到</span><span lang="EN-US"><span>2dB</span></span><span>之间</span><span lang="EN-US"><span>,</span></span><span>比复杂度</span><span lang="EN-US"><span>10</span></span><span>要高</span><span lang="EN-US"><span>,</span></span><span>但是</span><span lang="EN-US"><span>CPU</span></span><span>需要复杂度</span><span lang="EN-US"><span>10</span></span><span>大概</span><span lang="EN-US"><span>5</span></span><span>倍高行复杂度</span><span lang="EN-US"><span>1.</span></span><span>在实践中</span><span lang="EN-US"><span>,</span></span><span>最好的是设置在</span><span lang="EN-US"><span>2</span></span><span>到</span><span lang="EN-US"><span>4</span></span><span>之间</span><span lang="EN-US"><span>,</span></span><span>尽管更高的设定通常有用</span><span lang="EN-US"><span>,</span></span><span>当编码一个非对话声音</span><span lang="EN-US"><span>(non-speech sounds)</span></span><span>像</span><span lang="EN-US"><span>DTMF</span></span><span>语调</span><span lang="EN-US"><span>(tones).</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span><strong>变波特率<span>(VBR</span></strong></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>Variable bit-rate (VBR) allows a codec to change its bit-rate dynamically to adapt to</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>变波特率</span><span lang="EN-US"><span>(VBR)</span></span><span>允许编码动态地改变它的波特率以适应声音编码的</span><span lang="EN-US"><span>&#8221;</span></span><span>难度</span><span lang="EN-US"><span>&#8221;.</span></span><span>在</span><span lang="EN-US"><span>speex</span></span><span>举例来说</span><span lang="EN-US"><span>,</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>像元音</span><span lang="EN-US"><span>(vowel)</span></span><span>和瞬间高音</span><span lang="EN-US"><span>(high-enenrg transients)</span></span><span>需要个高的比特率来</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>取得一个不错的质量</span><span lang="EN-US"><span>,</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>而摩擦音</span><span lang="EN-US"><span>(fricative)</span></span><span>可以被充分地用相对较少的字节来进行编码</span><span lang="EN-US"><span>.</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>由于上面这个原因</span><span lang="EN-US"><span>,VBR</span></span><span>可以调节到一个低的比特率却达到一个同样的质量</span><span lang="EN-US"><span>,</span></span><span>或者用</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>某个比特率达到更好的质量</span><span lang="EN-US"><span>.</span></span><span>尽管有上面这些优点</span><span lang="EN-US"><span>,</span></span><span>但是</span><span lang="EN-US"><span>VBR</span></span><span>也有两个主要的缺点</span><span lang="EN-US"><span>.</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>首先</span><span lang="EN-US"><span>,</span></span><span>仅仅靠指定质量值</span><span lang="EN-US"><span>,</span></span><span>这里没有一个关于最后平均比特率的保证</span><span lang="EN-US"><span>.(</span></span><span>译者注</span><span lang="EN-US"><span>:</span></span><span>作者大概是想说没有什么明确的方法知道质量值</span><span lang="EN-US"><span>)</span></span><span>此外</span><span lang="EN-US"><span>,</span></span><span>对一些即时</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>通信</span><span lang="EN-US"><span>,</span></span><span>像</span><span lang="EN-US"><span>IP</span></span><span>电话</span><span lang="EN-US"><span>(VoIP)</span></span><span>这种包含着最大的比特率的</span><span lang="EN-US"><span>,</span></span><span>必须把比特率设为足够低以适应</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>传输通道</span><span lang="EN-US"><span>.</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>r</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span><strong>平均比特率<span>(ABR)</span></strong></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>平均比特率通过动态地调节</span><span lang="EN-US"><span>VBR</span></span><span>质量去得到一个确定的目标的比特率</span><span lang="EN-US"><span>,</span></span><span>从而解决了</span><span lang="EN-US"><span>VBR</span></span><span>中的一个问题</span><span lang="EN-US"><span>..</span></span><span>因为质量</span><span lang="EN-US"><span>/</span></span><span>比特率被即时的调整了</span><span lang="EN-US"><span>,</span></span><span>整体质量将会稍稍低于由</span><span lang="EN-US"><span>VBR</span></span><span>对一个</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>设置得和目标平均比特率非常接近的质量数编码得到的结果</span><span lang="EN-US"><span>.</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>&nbsp;</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span><strong>声音生动性检测<span>(VAD)</span></strong></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>声音生动性检测将会发觉音频正在被编码成对话</span><span lang="EN-US"><span>,</span></span><span>静音</span><span lang="EN-US"><span>,</span></span><span>或背景噪音</span><span lang="EN-US"><span>.VAD</span></span><span>总在用</span><span lang="EN-US"><span>VBR</span></span><span>进行编码时暗中起作用</span><span lang="EN-US"><span>,</span></span><span>因此选项仅仅对一个不是</span><span lang="EN-US"><span>VBR</span></span><span>的操作起作用</span><span lang="EN-US"><span>.</span></span><span>对于不是</span><span lang="EN-US"><span>VBR</span></span><span>的操作来说</span><span lang="EN-US"><span>,speex</span></span><span>察觉出一个不属于对话的周期</span><span lang="EN-US"><span>,</span></span><span>然后对它用足够的字节重新生成为背景噪音</span><span lang="EN-US"><span>.</span></span><span>不这叫做<span>舒适的噪音生成</span></span><span lang="EN-US"><span>(</span></span><span lang="EN-US"><span>CNG).</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span><strong>不连续传输<span>(DTX)</span></strong></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>不连续传输是</span><span lang="EN-US"><span>VAD/VBR</span></span><span>操作的一个额外选项</span><span lang="EN-US"><span>,</span></span><span>当背景噪音一定时</span><span lang="EN-US"><span>,</span></span><span>它可以完整地传输</span><span lang="EN-US"><span>.</span></span><span>因为在基于文件的操作中</span><span lang="EN-US"><span>,</span></span><span>我们不能停止对文件进行写入</span><span lang="EN-US"><span>,</span></span><span>所以只有</span><span lang="EN-US"><span>5</span></span><span>字节被这种帧所运用</span><span lang="EN-US"><span>.(</span></span><span>给</span><span lang="EN-US"><span>250bps</span></span><span>通信</span><span lang="EN-US"><span>)</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span><strong>Perceptual enhancement</strong></span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span><strong><span>知觉增强</span></strong></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>知觉增加是解码的一部分</span><span lang="EN-US"><span>,</span></span><span>它在打开的时候用来减少由编码解码所产生的噪音</span><span lang="EN-US"><span>.</span></span><span>在大都数</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>情况下</span><span lang="EN-US"><span>,</span></span><span>知觉增强在客观上使声音离原始值更远</span><span lang="EN-US"><span>(</span></span><span>如果用</span><span lang="EN-US"><span>SNR),</span></span><span>但是在最后它仍然听起来更好</span><span lang="EN-US"><span>(</span></span><span>主观上的改进</span><span lang="EN-US"><span>)</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span><strong>Algorithmic delay</strong></span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span><strong>迟时算法</strong></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>每一个声音编码导致了在传输上的延时</span><span lang="EN-US"><span>.</span></span><span>对于</span><span lang="EN-US"><span>speex,</span></span><span>这种延时等于</span><span lang="EN-US"><span>frame</span></span><span>的大小加上一些</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>数量的需要对每一帧进行的前瞻</span><span lang="EN-US"><span>(&#8221;look-adhead&#8221;).</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>在窄宽操作中</span><span lang="EN-US"><span>(8kHz),</span></span><span>迟时是</span><span lang="EN-US"><span>30ms,</span></span><span>而对于多频率</span><span lang="EN-US"><span>(2-44Hz),</span></span><span>迟时是</span><span lang="EN-US"><span>34ms.</span></span><span>这些值</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>不包括</span><span lang="EN-US"><span>CPU</span></span><span>编码</span><span lang="EN-US"><span>,</span></span><span>解码帧的时间</span><span lang="EN-US"><span>.</span></span>&nbsp;</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px"><span><strong>用<span>speex</span>编程<span>(the libspeex api)</span></strong></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>这个章节出要讲述了如何用</span><span lang="EN-US"><span>speex api</span></span><span>进行编程</span><span lang="EN-US"><span>.</span></span><span>例子的源代友你也可以在附录</span><span lang="EN-US"><span>B</span></span><span>中找到</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span><strong>4.1 Encoding</strong></span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span><strong><span>4.1</span>压缩</strong></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>为了用</span><span lang="EN-US"><span>Speex</span></span><span>压缩对话</span><span lang="EN-US"><span>,</span></span><span>你首先需要引用头文件</span><span lang="EN-US"><span>:</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>#include &lt;speex.h&gt;</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>然后你需要定义一个</span><span lang="EN-US"><span>Speex</span></span><span>的位采集</span><span lang="EN-US"><span>(bit-packing)</span></span><span>结构</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>SpeexBits bits;</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>and a Speex encoder state</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>以及定义一个</span><span lang="EN-US"><span>speex</span></span><span>编码器状态量</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>void *enc_state;</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>上面定义的这样被初始化</span><span lang="EN-US"><span>:</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>The two are initialized by:</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>speex_bits_init(&amp;bits);</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>enc_state = speex_encoder_init(&amp;speex_nb_mode);</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>为了支持多频率的压缩</span><span lang="EN-US"><span>,speex_nb_mode</span></span><span>将被</span><span lang="EN-US"><span>sppex_wb_mode</span></span><span>取代</span><span lang="EN-US"><span>.</span></span><span>在大都数</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>情况下</span><span lang="EN-US"><span>,</span></span><span>你需要知道你用的模式</span><span lang="EN-US"><span>(mode)</span></span><span>的帧</span><span lang="EN-US"><span>(frame)</span></span><span>的大小</span><span lang="EN-US"><span>,</span></span><span>你可以得到在</span><span lang="EN-US"><span>frame_size</span></span><span>变量里得到这值</span><span lang="EN-US"><span>:</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>speex_encoder_ctl(enc_state,SPEEX_GET_FRAME_SIZE,&amp;frame_size);</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>一但初始化完毕</span><span lang="EN-US"><span>,</span></span><span>对于每一个输入帧</span><span lang="EN-US"><span>:</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>speex_bits_reset(&amp;bits);</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>speex_encode(enc_state, input_frame, &amp;bits);</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>nbBytes = speex_bits_write(&amp;bits, byte_ptr, MAX_NB_BYTES);</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>上面</span><span lang="EN-US"><span>input_frame</span></span><span>是一个指向对话</span><span lang="EN-US"><span>(speech)</span></span><span>帧</span><span lang="EN-US"><span>(frame)</span></span><span>的</span><span lang="EN-US"><span>float</span></span><span>指针</span><span lang="EN-US"><span>(pointing);byte_ptr</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>是指向编码帧开始写的地方的</span><span lang="EN-US"><span>char</span></span><span>指针</span><span lang="EN-US"><span>,MAX_NB_BYTES</span></span><span>是能</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>写进</span><span lang="EN-US"><span>byte_ptr</span></span><span>而不会造成溢出的最大数</span><span lang="EN-US"><span>.nbBytes</span></span><span>是一个实际写入</span><span lang="EN-US"><span>btye_ptr</span></span><span>的数</span><span lang="EN-US"><span>,</span></span><span>即编码的实际大小</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>在调用</span><span lang="EN-US"><span>speex_bits_write</span></span><span>前</span><span lang="EN-US"><span>,</span></span><span>可能你需要调用</span><span lang="EN-US"><span>speex_bits_nbytes(&amp;bits)</span></span><span>得到需要写入</span><span lang="EN-US"><span>(write)</span></span><span>的字节大小</span><span lang="EN-US"><span>.</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>在你已经编码后</span><span lang="EN-US"><span>,</span></span><span>释放所有的资源</span><span lang="EN-US"><span>.</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>speex_bits_destroy(&amp;bits);</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>speex_encoder_destroy(enc_state);</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>That&#8217;s about it for the encoder.</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>&nbsp;</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>这就是关于编码的方面</span><span lang="EN-US"><span>.</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px"><span>&nbsp;</span></p>
<h4 id="subjcns!31B2F8637FF39314!276" class="TextColor1"><span>Speex manul中文版三</span></h4>
<div id="msgcns!31B2F8637FF39314!276">
<div>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>附源代码的翻译</span><span lang="EN-US"><span>:</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span><strong>B Sample code</strong></span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span><strong><span>B&nbsp;</span>例程源代码</strong></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>这个章节演示了一段用</span><span lang="EN-US"><span>speex</span></span><span>编码</span><span lang="EN-US"><span>,</span></span><span>解码对话</span><span lang="EN-US"><span>(speech)</span></span><span>的源代码</span><span lang="EN-US"><span>.</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>可以如下用</span><span lang="EN-US"><span>api</span></span><span>命令来编码并解码一个文件</span><span lang="EN-US"><span>:</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>译者注</span><span lang="EN-US"><span>:</span></span><span>这里说的</span><span lang="EN-US"><span>api</span></span><span>命令是指</span><span lang="EN-US"><span>unix</span></span><span>的用</span><span lang="EN-US"><span>&#8221;|&#8221;</span></span><span>进行管道写入读出</span><span lang="EN-US"><span>.</span></span><span>在</span><span lang="EN-US"><span>windows</span></span><span>下这样并不能实现</span><span lang="EN-US"><span>.</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>% sampleenc in_file.sw | sampledec out_file.sw</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>这里这两段代码都没有引用其它的头文件</span><span lang="EN-US"><span>,</span></span><span>并以</span><span lang="EN-US"><span>16&nbsp;</span></span><span>比特率</span><span lang="EN-US"><span>(bits)</span></span><span>进行编码</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>natural endianness).</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span><strong>B.1 sampleenc.c</strong></span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>Sameleenc&nbsp;</span></span><span>用一个未加工的</span><span lang="EN-US"><span>16</span></span><span>比特率</span><span lang="EN-US"><span>(bits)</span></span><span>文章</span><span lang="EN-US"><span>,</span></span><span>给它编码并产生一个</span><span lang="EN-US"><span>speex&nbsp;</span></span><span>流</span><span lang="EN-US"><span>(steam)</span></span><span>给标准输出</span><span lang="EN-US"><span>.</span></span><span>注意已压缩的和</span><span lang="EN-US"><span>speexenc/speexdec</span></span><span>不和谐</span><span lang="EN-US"><span>!</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>#include &lt;speex.h&gt;</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>#include &lt;stdio.h&gt;</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>/*</span></span><span>帧的大小在这个例程中是一个固定的值</span><span lang="EN-US"><span>,</span></span><span>但它并不是必须这样</span><span lang="EN-US"><span>*/</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>&nbsp;</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>#define FRAME_SIZE 160</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>int main(int argc, char **argv)</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>{</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>char *inFile;</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>FILE *fin;</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>short in[FRAME_SIZE];</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>float input[FRAME_SIZE];</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>char cbits[200];</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>int nbBytes;</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>/*</span></span><span>保存编码的状态</span><span lang="EN-US"><span>*/</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>void *state;</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>/*</span></span><span>保存字节因此他们可以被</span><span lang="EN-US"><span>speex</span></span><span>常规</span><span>读写</span><span lang="EN-US"><span>*/</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>&nbsp;</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>SpeexBits bits;</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>int i, tmp;</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>//</span></span><span>新建一个新的编码状态在窄宽</span><span lang="EN-US"><span>(narrowband)</span></span><span>模式下</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>state = speex_encoder_init(&amp;speex_nb_mode);</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>//</span></span><span>设置质量为</span><span lang="EN-US"><span>8(15kbps)</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>tmp=8;</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>speex_encoder_ctl(state, SPEEX_SET_QUALITY, &amp;tmp);</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>inFile = argv[1];</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>fin = fopen(inFile, "r");</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>//</span></span><span>初始化结构使他们保存数据</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>speex_bits_init(&amp;bits);</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>while (1)</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>{</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>//</span></span><span>读入一帧</span><span lang="EN-US"><span>16bits</span></span><span>的声音</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>fread(in, sizeof(short), FRAME_SIZE, fin);</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>if (feof(fin))</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>break;</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>//</span></span><span>把</span><span lang="EN-US"><span>16bits</span></span><span>的值转化为</span><span lang="EN-US"><span>float,</span></span><span>以便</span><span lang="EN-US"><span>speex</span></span><span>库可以在上面工作</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>for (i=0;i&lt;FRAME_SIZE;i++)</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>input[i]=in[i];</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>//</span></span><span>清空这个结构体里所有的字节</span><span lang="EN-US"><span>,</span></span><span>以便我们可以编码一个新的帧</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>speex_bits_reset(&amp;bits);</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>//</span></span><span>对帧进行编码</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>speex_encode(state, input, &amp;bits);</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>//</span></span><span>把</span><span lang="EN-US"><span>bits</span></span><span>拷贝到一个利用写出的</span><span lang="EN-US"><span>char</span></span><span>型数组</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>nbBytes = speex_bits_write(&amp;bits, cbits, 200);</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>//</span></span><span>首先写出帧的大小</span><span lang="EN-US"><span>,</span></span><span>这是</span><span lang="EN-US"><span>sampledec</span></span><span>文件需要的一个值</span><span lang="EN-US"><span>,</span></span><span>但是你的应用程序中可能不一样</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>fwrite(&amp;nbBytes, sizeof(int), 1, stdout);</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>//</span></span><span>写出压缩后的数组</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>fwrite(cbits, 1, nbBytes, stdout);</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>}</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>//</span></span><span>释放</span><span>编码器状态量</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>speex_encoder_destroy(state);</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>//</span></span><span>释放</span><span lang="EN-US"><span>bit_packing</span></span><span>结构</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>speex_bits_destroy(&amp;bits);</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>fclose(fin);</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>return 0;</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span lang="EN-US"><span>}</span></span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px" align="left"><span>&nbsp;</span></p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px"><span>&nbsp;</span></p></div></div>
<div class="postTitle"><a style="background-color: transparent; color: rgb(51,102,153); text-decoration: none; background-origin: initial; background-clip: initial" href="http://blog.donews.com/keo321/archive/2006/12/28/1104088.aspx"><span>如何使用Speex中的AEC模块，提高声音质量？</span></a></div>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">在Speex（<a style="background-color: transparent; color: rgb(51,102,153); text-decoration: none; background-origin: initial; background-clip: initial" href="http://www.speex.org/"><span>www.speex.org</span></a>）的最新版本中，开始集成了回音消除的模块，而回音消除一直是Voip之中亟待解决的主要问题。<br />很多朋友和我说speex的aec模块的效能并不好，我们先来看一下speex的aec的api调用方式。</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">/*<br />*创建AEC对象<br />*/<br />SpeexEchoState *echo_state = speex_echo_state_init(frame_size, filter_length);</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">frame_size 的取值最好是一个编码的frame大小， 在低带宽条件下，一般延迟20ms，而大小为160<br />filter_length,最好是房间内反射时间的1/3<br />如: 一个房间的反射时延为300ms<br />&nbsp;&nbsp;&nbsp; 那么这个filter_length就最好是100ms(这个长度又被称为tail length).</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">而其中filter_length的设定是一个关键。</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">/*<br />*执行AEC<br />*/<br />speex_echo_cancel(echo_state, input_frame, echo_frame, output_frame, residue);</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">其中:<br />input_frame: 就是被声卡捕捉到的声音<br />echo_frame: 是由扬声器播放出的声音,这个声音是需要从 input_frame中抵消的声音.</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">output_frame 是处理完以后输出的声音</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">residue是一个可选参数,如果不使用可以将之设置为NULL, 也可以通过preprocessor 来控制</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">问题的关键是 处理input和echo 之间的关系,<br />也就是说在捕捉到的信号和播放的信号之间的延迟必须足够的小,才可以提高效率.</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">writetosndcard(echo_frame, frame_size)<br />readfromsndcard(input_frame, frame_size)<br />speex_echo_cancel(echo_state, input_frame, echo_frame, output_frame, residue)<br />如果你想要尽可能的减小信号中的回音,那么可以将residue这个参数设置为噪音参数.</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">我相信在大多数情况下，都是因为声音捕捉和声音播放之间的同步问题没有处理好，导致的音频质量下降。</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">/*<br />*销毁和复位<br />*/<br />speex_echo_state_destroy(echo_state);</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">speex_echo_state_reset(echo_state);<br />不再复述了！</p>
<p style="line-height: 1.5; text-indent: 0px; margin: 10px auto; font-size: 13px">说明：<br />据说在Speex的最新的1.2beta版本上，Speex提供了可选择的，简化的API，来提高echo执行过程中的同步问题。</p></div><img src ="http://www.cppblog.com/tx7do/aggbug/195510.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2012-11-21 23:56 <a href="http://www.cppblog.com/tx7do/archive/2012/11/21/195510.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Speex 回声消除</title><link>http://www.cppblog.com/tx7do/archive/2012/11/21/195507.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Wed, 21 Nov 2012 15:44:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2012/11/21/195507.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/195507.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2012/11/21/195507.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/195507.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/195507.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 转载自:http://blog.csdn.net/dxpqxb/article/details/7928591为什么需要声学回声消除呢？在一般的VOIP软件或视频会议系统中，假设我们只有A和B两个人在通话，首先，A的声音传给B，B然后用喇叭放出来，而这时B的MIC呢则会采集到喇叭放出来的声音，然后传回给A，如果这个传输的过程中时延足够大，A就会听到一个和自己刚才说过的话一样的声音，这就是回声，...&nbsp;&nbsp;<a href='http://www.cppblog.com/tx7do/archive/2012/11/21/195507.html'>阅读全文</a><img src ="http://www.cppblog.com/tx7do/aggbug/195507.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2012-11-21 23:44 <a href="http://www.cppblog.com/tx7do/archive/2012/11/21/195507.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AEC (Acoustic Echo Canceller) 回音消除初探</title><link>http://www.cppblog.com/tx7do/archive/2012/11/21/195505.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Wed, 21 Nov 2012 15:23:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2012/11/21/195505.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/195505.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2012/11/21/195505.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/195505.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/195505.html</trackback:ping><description><![CDATA[<div><strong style="color: red">转载自:</strong><a style="color: red" href="http://www.cnblogs.com/rainbowzc/archive/2006/08/07/2422323.html"><strong>http://www.cnblogs.com/rainbowzc/archive/2006/08/07/2422323.html</strong></a><br /><br />
<p style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 10px auto; font: 13px/1.4 Verdana, Geneva, Arial, Helvetica, sans-serif; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">AEC回声抑制算法，这个比较难，目前可以使用directsound进行处理，不过只能在xp下使用，别的系统不支持！<br />目前gips对本算法有出色的实现，skype就是使用的该引擎！<br />要想自己实现，恐怕很困难！<br />&nbsp;</p>
<p style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 10px auto; font: 13px/1.4 Verdana, Geneva, Arial, Helvetica, sans-serif; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">AEC 模块是 Microsoft DirectSound 底层结构的一部分。该组件包括下列特性和限制：</p>
<p style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 10px auto; font: 13px/1.4 Verdana, Geneva, Arial, Helvetica, sans-serif; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">AEC只在不超过 25&#215;15&#215;9 英尺的小房间才会有效；<span class="Apple-converted-space">&nbsp;</span><br />AEC只对单声道有效，当输出是多个通道的立体声的时候，只有一个通道能够具有回波抵消的效果；<span class="Apple-converted-space">&nbsp;</span><br />AEC不能抵消来自其它声音源的声音，比如背景中收音机放出来的歌曲；<br />IDirectSoundFullDuplex8*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DirectSoundFD;//<br />IDirectSoundCaptureBuffer8*&nbsp; DirectSoundCaptureBuf8;//捕捉缓冲区接口指针<br />IDirectSoundBuffer8*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DirectSoundBuf8;//回放缓冲区接口指针<br />IDirectSoundBuffer8*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pIUnkown;//回放缓冲区接口指针</p>
<p style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 10px auto; font: 13px/1.4 Verdana, Geneva, Arial, Helvetica, sans-serif; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">extern "C" const GUID IID_IDirectSoundBuffer8 = {0x6825a449, 0x7524, 0x4d82,{ 0x92, 0x0f, 0x50, 0xe3, 0x6a, 0xb3, 0xab, 0x1e}};<br />extern "C" const GUID GUID_DSCFX_MS_NS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = {0x11c5c73b, 0x66e9, 0x4ba1, {0xa0, 0xba, 0xe8, 0x14, 0xc6, 0xee, 0xd9, 0x2d}};<br />extern "C" const GUID GUID_DSCFX_CLASS_NS = {0xe07f903f, 0x62fd, 0x4e60, {0x8c, 0xdd, 0xde, 0xa7, 0x23, 0x66, 0x65, 0xb5}};<br />extern "C" const GUID GUID_DSCFX_MS_AEC = {0xcdebb919, 0x379a, 0x488a, {0x87, 0x65, 0xf5, 0x3c, 0xfd, 0x36, 0xde, 0x40}};<br />extern "C" const GUID GUID_DSCFX_CLASS_AEC = {0xBF963D80L, 0xC559, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}};<br />extern "C" const GUID DAlgorithm ={0x00000000,&nbsp; 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};</p>
<p style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 10px auto; font: 13px/1.4 Verdana, Geneva, Arial, Helvetica, sans-serif; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><br />//1.创建及初始化DirectSound<br />WAVEFORMATEX WaveDataFormat={WAVE_FORMAT_PCM, 1,8000,16000,2,16, 0};&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Apple-converted-space">&nbsp;</span><br />//回放缓冲区。render buffer<br />DSBUFFERDESC desc;<br />memset(&amp;desc, 0, sizeof(desc));<span class="Apple-converted-space">&nbsp;</span><br />desc.dwSize = sizeof(desc);<br />desc.dwFlags = DSBCAPS_CTRLFX | DSBCAPS_GLOBALFOCUS;<br />desc.dwBufferBytes = 2000 * NUM_REC_NOTIFICATIONS;//待定<br />desc.dwReserved = 0;<br />desc.lpwfxFormat = &amp;WaveDataFormat;<br />&nbsp;&nbsp;&nbsp;</p>
<p style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 10px auto; font: 13px/1.4 Verdana, Geneva, Arial, Helvetica, sans-serif; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">//捕捉缓冲区AEC和NS效果。<br />DSCEFFECTDESC efft[2];<br />memset(efft, 0, sizeof(efft));<br />//AEC效果<br />efft[0].dwSize = sizeof(efft[0]);<br />efft[0].dwFlags = DSCFX_LOCSOFTWARE;<br />efft[0].guidDSCFXClass = GUID_DSCFX_CLASS_AEC;<br />efft[0].guidDSCFXInstance = GUID_DSCFX_MS_AEC;<br />//NS效果<br />efft[1].dwSize = sizeof(efft[1]);<br />efft[1].dwFlags = DSCFX_LOCSOFTWARE;<br />efft[1].guidDSCFXClass = GUID_DSCFX_CLASS_NS;<br />efft[1].guidDSCFXInstance = GUID_DSCFX_MS_NS;<br />&nbsp;&nbsp;&nbsp;<span class="Apple-converted-space">&nbsp;</span><br />//捕捉缓冲区。capture buffer<br />DSCBUFFERDESC cdesc;<br />memset(&amp;cdesc, 0, sizeof(cdesc));<br />cdesc.dwSize = sizeof(cdesc);<br />cdesc.dwFlags = DSCBCAPS_CTRLFX;<span class="Apple-converted-space">&nbsp;</span><br />cdesc.dwBufferBytes =&nbsp; 2000 * NUM_REC_NOTIFICATIONS;//待定<br />cdesc.lpwfxFormat = &amp;WaveDataFormat;<br />cdesc.dwFXCount = 2;<br />cdesc.lpDSCFXDesc = efft;</p>
<p style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 10px auto; font: 13px/1.4 Verdana, Geneva, Arial, Helvetica, sans-serif; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">HWND win = AfxGetApp()-&gt;m_pMainWnd-&gt;m_hWnd;<br />hr = DirectSoundFullDuplexCreate8(0, 0,&amp;cdesc, &amp;desc,win,<span class="Apple-converted-space">&nbsp;</span><br />DSSCL_PRIORITY,&amp;DirectSoundFD, &amp;DirectSoundCaptureBuf8,&amp;DirectSoundBuf8, 0);<span class="Apple-converted-space">&nbsp;</span><br />DXTRACE_ERR( TEXT("DirectSoundFullDuplexCreate8"), hr );<br />//成功创建DirectSoundFD，DirectSoundCaptureBuf8，DirectSoundBuf8，均不为零。</p>
<p style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 10px auto; font: 13px/1.4 Verdana, Geneva, Arial, Helvetica, sans-serif; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">if(!FAILED(hr))<br />&nbsp;&nbsp;&nbsp; DirectSoundFD-&gt;QueryInterface(IID_IDirectSoundBuffer8, (void**)pIUnkown);<br />//发现上面的pIUnkown=0，查询失败，为什么？<br />&nbsp;&nbsp;&nbsp; AfxMessageBox("失败");</p></div><img src ="http://www.cppblog.com/tx7do/aggbug/195505.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2012-11-21 23:23 <a href="http://www.cppblog.com/tx7do/archive/2012/11/21/195505.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Silk codec的一些资料</title><link>http://www.cppblog.com/tx7do/archive/2012/11/16/195277.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Fri, 16 Nov 2012 09:18:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2012/11/16/195277.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/195277.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2012/11/16/195277.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/195277.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/195277.html</trackback:ping><description><![CDATA[<p style="padding-bottom: 0px; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 10px auto; padding-left: 0px; padding-right: 0px; font: 14px/25px verdana, Arial, Helvetica, sans-serif; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; padding-top: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><strong style="color: red">转载自:</strong><a style="color: red" href="http://www.cnblogs.com/c6000/archive/2011/03/17/1986609.html"><strong>http://www.cnblogs.com/c6000/archive/2011/03/17/1986609.html</strong></a><br /><br />Skype表示它最近将开始向第三方开发人员和硬件制造商提供免版税认证(RF)的Silk宽带音频编码器。</p>
<p style="padding-bottom: 0px; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 10px auto; padding-left: 0px; padding-right: 0px; font: 14px/25px verdana, Arial, Helvetica, sans-serif; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; padding-top: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">Silk下载地址如下</p>
<p style="padding-bottom: 0px; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 10px auto; padding-left: 0px; padding-right: 0px; font: 14px/25px verdana, Arial, Helvetica, sans-serif; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; padding-top: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><a style="border-bottom: rgb(51,51,51) 1px dotted; padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; color: rgb(0,0,0); text-decoration: none; padding-top: 0px" href="http://developer.skype.com/silk/SILK_SDK_SRC_v1.0.7.zip">http://developer.skype.com/silk/SILK_SDK_SRC_v1.0.7.zip</a></p>
<p style="padding-bottom: 0px; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 10px auto; padding-left: 0px; padding-right: 0px; font: 14px/25px verdana, Arial, Helvetica, sans-serif; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; padding-top: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">Silk标准下载地址如下</p>
<p style="padding-bottom: 0px; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 10px auto; padding-left: 0px; padding-right: 0px; font: 14px/25px verdana, Arial, Helvetica, sans-serif; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; padding-top: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><a style="border-bottom: rgb(51,51,51) 1px dotted; padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; color: rgb(0,0,0); text-decoration: none; padding-top: 0px" href="http://tools.ietf.org/html/draft-vos-silk-01">http://tools.ietf.org/html/draft-vos-silk-01</a></p>
<p style="padding-bottom: 0px; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 10px auto; padding-left: 0px; padding-right: 0px; font: 14px/25px verdana, Arial, Helvetica, sans-serif; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; padding-top: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">Silk的一些文档</p>
<p style="padding-bottom: 0px; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 10px auto; padding-left: 0px; padding-right: 0px; font: 14px/25px verdana, Arial, Helvetica, sans-serif; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; padding-top: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><a style="border-bottom: rgb(51,51,51) 1px dotted; padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; color: rgb(0,0,0); text-decoration: none; padding-top: 0px" href="http://developer.skype.com/silk">http://developer.skype.com/silk</a></p>
<p style="padding-bottom: 0px; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 10px auto; padding-left: 0px; padding-right: 0px; font: 14px/25px verdana, Arial, Helvetica, sans-serif; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; padding-top: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">Silk简介</p>
<p style="padding-bottom: 0px; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 10px auto; padding-left: 0px; padding-right: 0px; font: 14px/25px verdana, Arial, Helvetica, sans-serif; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; padding-top: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">SILK最早在Windows版Skype的4.0版本中被披露,它成为了Skype到Skype通话的默认解码器,实时带宽6-40Kbps即可工作,即使丢包水平达到10%依然可以稳定维持24KHz采样的通话音质.</p>
<p style="padding-bottom: 0px; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 10px auto; padding-left: 0px; padding-right: 0px; font: 14px/25px verdana, Arial, Helvetica, sans-serif; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; padding-top: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><span style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: Arial; padding-top: 0px" face="Arial">Skype投入了数百万美元，耗时三年多开发了Silk，他们表示Silk可以使VoIP通话听起来好像你和对话的人在同一间房子里一样。大部分电话只能传输3.4kHz(码率)的信号，而Silk可以让Skype传输高达12kHz的信号。</span></p>
<p style="padding-bottom: 0px; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 10px auto; padding-left: 0px; padding-right: 0px; font: 14px/25px verdana, Arial, Helvetica, sans-serif; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; padding-top: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><span style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: Arial; padding-top: 0px" face="Arial">开放编码器可以被看作是Skype放弃了一项竞争优势，但是它是Skype将其服务推广到更多设备这一长期战略中的一环。该公司已经有4.05亿套软件的装机量，其中绝大部分用户是台式计算机用户。免费提供其编码器可以让设备制造商将Skype整合到像智能电话、手机或移动互联设备中去。</span><span style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: Arial; padding-top: 0px" face="Arial">Skype已经开始着手将其服务推广到其它平台上，并发布了基于Android和支持Java手机的通话服务。该公司还和诺基亚合作将其VoIP软件预装到智能手机上，例如N97。</span></p><img src ="http://www.cppblog.com/tx7do/aggbug/195277.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2012-11-16 17:18 <a href="http://www.cppblog.com/tx7do/archive/2012/11/16/195277.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>混音器编程接口讨论</title><link>http://www.cppblog.com/tx7do/archive/2012/11/05/194617.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Mon, 05 Nov 2012 10:23:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2012/11/05/194617.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/194617.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2012/11/05/194617.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/194617.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/194617.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 转载自:http://www.cnblogs.com/windviki/archive/2011/08/31/2160683.html混音器编程接口讨论翻译：windviki@gmail.com&nbsp;转载请注明译自：MIXER API ARGUMENTATION为了理解混音器API是如何工作的，必须先了解典型的声卡的硬件布局。我们有必要想象一下，声卡上有各种独...&nbsp;&nbsp;<a href='http://www.cppblog.com/tx7do/archive/2012/11/05/194617.html'>阅读全文</a><img src ="http://www.cppblog.com/tx7do/aggbug/194617.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2012-11-05 18:23 <a href="http://www.cppblog.com/tx7do/archive/2012/11/05/194617.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CxImage使用掩码色设置透明色的图</title><link>http://www.cppblog.com/tx7do/archive/2012/11/01/194161.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Thu, 01 Nov 2012 07:05:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2012/11/01/194161.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/194161.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2012/11/01/194161.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/194161.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/194161.html</trackback:ping><description><![CDATA[CxImage设置透明色的方法:<br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" alt="" /><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;SetImageTransColor(&nbsp;CxImage</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;pImg,&nbsp;BYTE&nbsp;R,&nbsp;BYTE&nbsp;G,&nbsp;BYTE&nbsp;B&nbsp;)<br /><img id="Codehighlighter1_65_250_Open_Image" onclick="this.style.display='none'; Codehighlighter1_65_250_Open_Text.style.display='none'; Codehighlighter1_65_250_Closed_Image.style.display='inline'; Codehighlighter1_65_250_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_65_250_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_65_250_Closed_Text.style.display='none'; Codehighlighter1_65_250_Open_Image.style.display='inline'; Codehighlighter1_65_250_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_65_250_Closed_Text"><img src="http://www.cppblog.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_65_250_Open_Text"><span style="color: #000000">{<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(pImg&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;NULL)&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(pImg</span><span style="color: #000000">-&gt;</span><span style="color: #000000">GetTransIndex()&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">24</span><span style="color: #000000">)<br /><img id="Codehighlighter1_129_157_Open_Image" onclick="this.style.display='none'; Codehighlighter1_129_157_Open_Text.style.display='none'; Codehighlighter1_129_157_Closed_Image.style.display='inline'; Codehighlighter1_129_157_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_129_157_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_129_157_Closed_Text.style.display='none'; Codehighlighter1_129_157_Open_Image.style.display='inline'; Codehighlighter1_129_157_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_129_157_Closed_Text"><img src="http://www.cppblog.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_129_157_Open_Text"><span style="color: #000000">{<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pImg</span><span style="color: #000000">-&gt;</span><span style="color: #000000">IncreaseBpp(</span><span style="color: #000000">24</span><span style="color: #000000">);<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;pImg</span><span style="color: #000000">-&gt;</span><span style="color: #000000">SetTransIndex(</span><span style="color: #000000">0</span><span style="color: #000000">);<br /><img id="Codehighlighter1_204_215_Open_Image" onclick="this.style.display='none'; Codehighlighter1_204_215_Open_Text.style.display='none'; Codehighlighter1_204_215_Closed_Image.style.display='inline'; Codehighlighter1_204_215_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_204_215_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_204_215_Closed_Text.style.display='none'; Codehighlighter1_204_215_Open_Image.style.display='inline'; Codehighlighter1_204_215_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;RGBQUAD&nbsp;rgbTrans&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_204_215_Closed_Text"><img src="http://www.cppblog.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_204_215_Open_Text"><span style="color: #000000">{B,&nbsp;G,&nbsp;R,&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">}</span></span><span style="color: #000000">;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;pImg</span><span style="color: #000000">-&gt;</span><span style="color: #000000">SetTransColor(rgbTrans);<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" alt="" />}</span></span></div>经过这样设置透明色的图,如果使用CxImage::Stretch进行缩放绘制,绘制透明色并不会透明,而会原汁原味的将透明色如实的绘制上去,经过测试,使用CxImage::Draw2这个方法缩放绘制是没有问题的.<img src ="http://www.cppblog.com/tx7do/aggbug/194161.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2012-11-01 15:05 <a href="http://www.cppblog.com/tx7do/archive/2012/11/01/194161.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Skype SILK vs. iLBC vs. Speex</title><link>http://www.cppblog.com/tx7do/archive/2012/10/24/193779.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Wed, 24 Oct 2012 07:06:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2012/10/24/193779.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/193779.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2012/10/24/193779.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/193779.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/193779.html</trackback:ping><description><![CDATA[<div><strong style="color: red">转载自:</strong><a style="color: red" href="http://blog.csdn.net/wanggp_2007/article/details/5540686"><strong>http://blog.csdn.net/wanggp_2007/article/details/5540686</strong></a><br /><br />
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">对比一下这三种VOIP语音算法的特点:</p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;</p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">1 参数与特征</p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;</p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none; border-image: initial" alt="" src="http://hi.csdn.net/attachment/201004/28/0_12724708406VXX.gif" /></p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;</p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">2 SILK性能</p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;</p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none; border-image: initial" alt="" src="http://hi.csdn.net/attachment/201004/28/0_1272469009ldFP.gif" /></p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;</p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none; border-image: initial" alt="" src="http://hi.csdn.net/attachment/201004/28/0_1272469047QpEs.gif" /></p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;</p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;&nbsp; 关于iLBC和Speex的性能可以参考以前写的文章。</p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;</p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">3 关于VOIP一些观点（仅代表个人观点）</p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;</p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;&nbsp;1)&nbsp;&nbsp;Skype 辛苦三年开发的SILK为什么要开源？</p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;&nbsp; &nbsp; &nbsp; 第一，技术上，其实SILK用到了很多Royalty Free的算法部分，遵循开源的法则，取之于民，用之于民；</p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;&nbsp; &nbsp; &nbsp; 第二，商业上，Skype 根本不靠Codec赚钱，他本身最大的优势是网络条件做的比较好，这种环境下无论是SILK、iLBC还是G.729都可以达成比较不错的音质。</p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;&nbsp; &nbsp; &nbsp; 第三，口碑上，提高知名度，都已经把SILK定点好了，将来一定会有很多第三方去推广，广告、市场和口碑双赢；</p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;</p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;&nbsp; 2）iLBC一定就比Speex质量好吗？</p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;&nbsp; &nbsp; &nbsp; 根据目前的评测，当二者的编码速率差不多时，iLBC的质量要好于Speex，但是也有一些牛人认为iLBC这种每帧独立编码的思想其实是低效率的，通过增加编码冗余也可以达到相同的音质，意思是将CELP编码器增加一些前后冗余信息适当提高码率，也可以提高丢包情况下的抗干扰性，这个暂时还没有定论。</p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;</p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;&nbsp; 3）Speex 总感觉用的人少？</p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;&nbsp; &nbsp;到底是Speex的推广差、维护差，还是音质差？虽然Speex的开发者出来解释了很多原因，可是目前好像用的第三方不是很多，同时我也感觉它的音质好像是有一点差。</p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;</p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;&nbsp; 4）有了SILK，还有人用iLBC吗？</p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;&nbsp; &nbsp;SILK和iLBC来自两个不同公司skype and GIPS，个人感觉会同时存在。</p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;</p>
<p style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">好了，欢迎大家对以上观点进行补充，谢谢！</p><br class="Apple-interchange-newline" /></div><img src ="http://www.cppblog.com/tx7do/aggbug/193779.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2012-10-24 15:06 <a href="http://www.cppblog.com/tx7do/archive/2012/10/24/193779.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Google开源实时通信项目WebRTC</title><link>http://www.cppblog.com/tx7do/archive/2012/10/24/193776.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Wed, 24 Oct 2012 06:26:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2012/10/24/193776.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/193776.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2012/10/24/193776.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/193776.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/193776.html</trackback:ping><description><![CDATA[<div><strong style="color: red">转载自:</strong><a style="color: red" href="http://www.infoq.com/cn/news/2011/06/google-webrtc"><strong>http://www.infoq.com/cn/news/2011/06/google-webrtc</strong></a><br /><br />
<div style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 13px/19px Lucida, 'Lucida Grande', Tahoma, sans-serif; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" id="newsContent">
<p>最近，Google正式开源了<a style="color: rgb(11,89,178); text-decoration: underline" href="http://sites.google.com/site/webrtc/home">WebRTC实时通信项目</a>，希望浏览器厂商能够将该技术内建在浏览器中，从而使Web应用开发人员能够通过HTML标签和JavaScript API就实现Web音频、视频通信功能。</p>
<p>WebRTC（Web Real Time Communication）并不是Google原来自己的技术。在2010年，Google以大约6820万美元<a style="color: rgb(11,89,178); text-decoration: underline" href="http://www.computerworld.com/s/article/9176906/Google_to_acquire_voice_and_video_codec_company">收购</a>了VoIP软件开发商Global IP Solutions公司，并因此获得了该公司拥有的WebRTC技术。如今，互联网的音频、视频通信服务技术一般都是私有技术，如<a style="color: rgb(11,89,178); text-decoration: underline" href="http://www.skype.com/">Skype</a>， 需要通过安装插件或者桌面客户端来实现通信功能。Google希望Web开发人员能够直接在浏览器中创建视频或语音聊天应用，Global IP Solutions公司之前已经针对Android、Windows Mobile、iPhone制作了基于WebRTC的移动客户端。Google此次将WebRTC开源出来，就是希望浏览器厂商能够将该技术直接内嵌到浏 览器中，从而方便Web开发人员。</p>
<p>WebRTC的<a style="color: rgb(11,89,178); text-decoration: underline" href="http://sites.google.com/site/webrtc/blog">博客</a>说明了WebRTC的优势和发展方向：</p>
<blockquote style="background-image: url(http://cdn2.infoq.com/styles/cn/i/bg-blockquote.gif); border-bottom: rgb(239,239,239) 2px solid; border-left: rgb(239,239,239) 2px solid; padding-bottom: 5px; background-color: rgb(250,250,250); padding-left: 5px; padding-right: 5px; background-position: 5px 5px; color: rgb(51,51,51); margin-left: 20px; border-top: rgb(239,239,239) 2px solid; margin-right: 0px; border-right: rgb(239,239,239) 2px solid; padding-top: 5px; border-image: initial; background-origin: initial; background-clip: initial">
<p style="margin-top: 0px">直到现在，实时通信仍然需要私有的信号处理技术，大部分都是通过插件和客户端来安装使用。我们通过WebRTC开源了收购GIPS后获得的音频、视频引擎技术，让开发人员能够了解信号处理技术，并使用了BSD风格的<a style="color: rgb(11,89,178); text-decoration: underline" href="http://sites.google.com/site/webrtc/license-rights/license">授权</a>。这会支持开发人员通过简单的HTML和JavaScript API创建音频和视频聊天应用。</p>
<p style="margin-bottom: 0px">我们正在与其他浏览器开发厂商Mozilla和Opera等紧密合作，尽快在浏览器中实现这项技术以便于Web社区使用。此外，我们还积极地参与IETF和W3C工作组的活动，定义和实现一套实时通信标准。</p></blockquote>
<p>其<a style="color: rgb(11,89,178); text-decoration: underline" href="http://sites.google.com/site/webrtc/faq">官网</a>上列表了使用WebRTC技术的四个理由：</p>
<ol><li>互联网成功的一个关键因素是一些核心技术如HTML、HTTP和TCP/IP是开放和免费实现的。目前，在浏览器通信领域还没有免费、高质量、完整的解决方案。WebRTC就是这样的技术。</li><li>该技术已经集成了最佳的音频、视频引擎，并被部署到数以百万级的终端中，经过超过8年的磨练。Google不会从该技术中收取费用。</li><li>包含了使用STUN、ICE、TURN、RTP-over-TCP的关键NAT和防火墙穿越技术，并支持代理。</li><li>构建在浏览器中，WebRTC通过提供直接映射到PeerConnection的信号状态机来抽象信号处理。Web开发人员因此可以选择适合应用场景的协议（例如：SIP、XMPP/Jingle等等）。</li></ol>
<p>WebRTC的架构图如下所示：</p>
<p align="center"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-image: initial" alt="" src="http://www.infoq.com/resource/news/2011/06/google-webrtc/zh/resources/11.png" _p="true" _href="img://11.png" /></p>
<p align="center">图 1 &nbsp;WebRTC架构图（图片来源：WebRTC官方网站）</p>
<p>关于架构图的组成部分，包括：</p>
<blockquote style="background-image: url(http://cdn2.infoq.com/styles/cn/i/bg-blockquote.gif); border-bottom: rgb(239,239,239) 2px solid; border-left: rgb(239,239,239) 2px solid; padding-bottom: 5px; background-color: rgb(250,250,250); padding-left: 5px; padding-right: 5px; background-position: 5px 5px; color: rgb(51,51,51); margin-left: 20px; border-top: rgb(239,239,239) 2px solid; margin-right: 0px; border-right: rgb(239,239,239) 2px solid; padding-top: 5px; border-image: initial; background-origin: initial; background-clip: initial">Web API&#8212;&#8212;第三方开发人员用来开发基于Web的应用，如视频聊天。<br />WebRTC Native C++ API&#8212;&#8212;浏览器厂商用于实现Web API的函数集。<br />Session Management&#8212;&#8212;抽象session层，支持调用构建和管理层，由应用开发者来决定如何实现协议。<br />VoiceEngine&#8212;&#8212;音频媒体链的框架，从声卡到网络。<br />iSAC&#8212;&#8212;一种用于VoIP和流音频的宽带和超宽带音频编解码器，iSAC采用16 kHz或32 kHz的采样频率和12&#8212;52 kbps的可变比特率。<br />iLBC&#8212;&#8212;用于VoIP和流音频的窄带语音编解码器，使用8 kHZ的采样频率，20毫秒帧比特率为15.2 kbps，30毫米帧的比特率为13.33 kbps，标准由IETF RFC 3951和3952定义。<br />NetEQ for Voice&#8212;&#8212;动态抖动缓存和错误隐藏算法，用于缓解网络抖动和丢包引起的负面影响。在保持高音频质量的同时尽可能降低延迟。<br />VideoEngine&#8212;&#8212;视频媒体链的框架，从相机像头到网络，从网络到屏幕。<br />VP8&#8212;&#8212;来自于WebM项目的视频编解码器，非常适合RTC，因为它是为低延迟而设计开发的。<br />Image enhancements&#8212;&#8212;消除通过摄像头获取的图片的视频噪声等。<br />其他更详细的架构分析可以查看这里的<a style="color: rgb(11,89,178); text-decoration: underline" href="http://sites.google.com/site/webrtc/reference/webrtc-components">文档</a>。</blockquote>
<p>PeerConnection位于WebRTC Native C++ API的最上层，它的代码实现来源于<a style="color: rgb(11,89,178); text-decoration: underline" href="http://code.google.com/apis/talk/libjingle/index.html">libjingle</a>（一款p2p开发工具包），目前被应用于WebRTC中。其中关键的两个类定义是：</p>
<blockquote style="background-image: url(http://cdn2.infoq.com/styles/cn/i/bg-blockquote.gif); border-bottom: rgb(239,239,239) 2px solid; border-left: rgb(239,239,239) 2px solid; padding-bottom: 5px; background-color: rgb(250,250,250); padding-left: 5px; padding-right: 5px; background-position: 5px 5px; color: rgb(51,51,51); margin-left: 20px; border-top: rgb(239,239,239) 2px solid; margin-right: 0px; border-right: rgb(239,239,239) 2px solid; padding-top: 5px; border-image: initial; background-origin: initial; background-clip: initial">class &nbsp;PeerConnectionObserver {<br />public:<br />&nbsp;virtual void OnError();<br />&nbsp;virtual void OnSignalingMessage(const std::string&amp; msg);<br />&nbsp;virtual void OnAddStream(const std::string&amp; stream_id,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int channel_id,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bool video);<br />&nbsp;virtual void OnRemoveStream(const std::string&amp; stream_id,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int channel_id,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bool video);<br />}; 
<p>该类定义了一个抽象的观察者。开发人员应该继承实现自己的观察者类。</p>class &nbsp;PeerConnection {<br />public:<br />&nbsp;explicit PeerConnection(const std::string&amp; config);<br />&nbsp;bool Initialize();<br />&nbsp;void RegisterObserver(PeerConnectionObserver* observer);<br />&nbsp;bool SignalingMessage(const std::string&amp; msg);<br />&nbsp;bool AddStream(const std::string&amp; stream_id, bool video);<br />&nbsp;bool RemoveStream(const std::string&amp; stream_id);<br />&nbsp;bool Connect();<br />&nbsp;void Close();<br />&nbsp;bool SetAudioDevice(const std::string&amp; wave_in_device,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const std::string&amp; wave_out_device);<br />&nbsp;bool SetLocalVideoRenderer(cricket::VideoRenderer* renderer);<br />&nbsp;bool SetVideoRenderer(const std::string&amp; stream_id,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cricket::VideoRenderer* renderer);<br />&nbsp;bool SetVideoCapture(const std::string&amp; cam_device);<br />};<br />
<p style="margin-bottom: 0px">具体的函数说明可以查看相应的<a style="color: rgb(11,89,178); text-decoration: underline" href="http://sites.google.com/site/webrtc/reference#TOC-PeerConnection-Native-APIs">API介绍</a>。</p></blockquote>
<p>正如Google所说的，它一直在参与制定和实现HTML 5标准中的<a style="color: rgb(11,89,178); text-decoration: underline" href="http://www.whatwg.org/specs/web-apps/current-work/complete/video-conferencing-and-peer-to-peer-communication.html">视频会议和p2p通信部分</a>，虽然还不是正式标准，但是我们可以从草案的示例中看到未来Web开发人员的使用情况：</p>
<blockquote style="background-image: url(http://cdn2.infoq.com/styles/cn/i/bg-blockquote.gif); border-bottom: rgb(239,239,239) 2px solid; border-left: rgb(239,239,239) 2px solid; padding-bottom: 5px; background-color: rgb(250,250,250); padding-left: 5px; padding-right: 5px; background-position: 5px 5px; color: rgb(51,51,51); margin-left: 20px; border-top: rgb(239,239,239) 2px solid; margin-right: 0px; border-right: rgb(239,239,239) 2px solid; padding-top: 5px; border-image: initial; background-origin: initial; background-clip: initial">// the first argument describes the STUN/TURN server configuration<br />var local = new PeerConnection('TURNS example.net', sendSignalingChannel);<br />local.signalingChannel(...); // if we have a message from the other side, pass it along here<br />// (aLocalStream is some GeneratedStream object)<br />local.addStream(aLocalStream); // start sending video<br />function sendSignalingChannel(message) {<br />&nbsp;... // send message to the other side via the signaling channel<br />}<br />function receiveSignalingChannel (message) {<br />&nbsp;// call this whenever we get a message on the signaling channel<br />&nbsp;local.signalingChannel(message);<br />}<br />local.onaddstream = function (event) {<br />&nbsp;// (videoElement is some &lt;video&gt; element)<br />&nbsp;videoElement.src = URL.getObjectURL(event.stream);<br />};<br /></blockquote>
<p>目前有关Web实时通信的技术标准正在制定当中，W3C的<a style="color: rgb(11,89,178); text-decoration: underline" href="http://www.w3.org/2011/04/webrtc-charter.html">Web Real-Time Communication工作组</a>今年五月份刚刚正式成立，并计划在今年第三季度发布第一个公开草案，从其工作组的路线图中可以看出，正式的推荐标准预计将在2013年第一季度发布，有关W3C标准是否会对WebRTC项目的发展有所影响，未来还要看草案的具体细节。</p>
<p>Google希望开源的WebRTC技术能够获得越来越多的浏览器厂商支持，WebRTC的网站已经宣布将在Chrome、Firefox和Opera上实现相应的API接口。Opera首席技术官H&#229;kon Wium Lie对媒体<a style="color: rgb(11,89,178); text-decoration: underline" href="http://www.theregister.co.uk/2011/06/01/google_open_sources_webrtc/">表示</a>，Google能够把价值不菲的代码贡献出来非常了不起，Opera一直希望能够在浏览器中实现实时通信技术。</p>
<p>提到实时通信技术，不得不让人想起行业巨头Skype。巧合的是，就在前不久，微软刚刚斥资85亿美元现金<a style="color: rgb(11,89,178); text-decoration: underline" href="http://news.ifeng.com/gundong/detail_2011_05/11/6302654_0.shtml">收购</a>网络电话服务商Skype，当时有许多分析师指出，<a style="color: rgb(11,89,178); text-decoration: underline" href="http://www.infoq.com/cn/news/2011/05/microsoft-skype">微软的收购将直面Google的竞争</a>：</p>
<blockquote style="background-image: url(http://cdn2.infoq.com/styles/cn/i/bg-blockquote.gif); border-bottom: rgb(239,239,239) 2px solid; border-left: rgb(239,239,239) 2px solid; padding-bottom: 5px; background-color: rgb(250,250,250); padding-left: 5px; padding-right: 5px; background-position: 5px 5px; color: rgb(51,51,51); margin-left: 20px; border-top: rgb(239,239,239) 2px solid; margin-right: 0px; border-right: rgb(239,239,239) 2px solid; padding-top: 5px; border-image: initial; background-origin: initial; background-clip: initial">
<p style="margin-top: 0px">&#8230;...收购也挫败了竞争对手Google利用Skype技术完善通话服务的计划。</p>
<p>MSN即时通讯、必应（bing）搜索、网络广告等成了微软在互联网领域迎战谷歌的三大阵地。然而，相对于谷歌在互联网行业的呼风唤雨，微软的互联网战略一直没有真正展现出让业界看到其能够挑战谷歌的核心优势。</p>
<p>谷歌和苹果都已经在网络电话上投入了数年时间。苹果一直在力推iChat和FaceTime，谷歌也在普及其网络通信相关产品Chat和Voice。不过，谷歌和苹果都有一个共同的问题，他们很难在竞争对手的平台上生存。苹果用户无法和谷歌以及微软的用户进行视频聊天，谷歌在跨 平台方面做了很多努力，但是仍有不少障碍。</p>
<p>不过Skype则没有这一问题，作为免费服务的Skype可以运行在苹果、Linux以及Windows电脑上，也支持Android和iPhone等手机平台，甚至可以在电视机上运行。</p>
<p style="margin-bottom: 0px">收购Skype，微软不仅仅是为了从中受益，微软还希望借此使Skype远离谷歌的&#8220;魔爪&#8221;。如果谷歌收购了Skype，这对微软来说无疑是一个沉重的打击。想想吧，如果谷歌收购了Skype，并将Skype整合进Google Apps、Gmail、Google Talk和Google Voice等谷歌产品之中，再想想如果谷歌将Skype与Android平台进行一些深度整合，这对微软来说，无疑是一场灾难。即便微软并未很好的将Skype整合进自家产品之中，但这也避免了谷歌通过收购Skype来获得巨大的价值。</p></blockquote>
<p>就在微软收购Skype不久，Google就宣布对WebRTC开源，这不免让人有所联想。有国外媒体<a style="color: rgb(11,89,178); text-decoration: underline" href="http://thenextweb.com/google/2011/06/01/google-releases-developer-preview-of-webrtc-its-open-real-time-voice-and-video-platform/">评论</a>说，Google此次开源是想让广大用户远离该行业的领导者如Skype和Apple的FaceTime平台。通过浏览器来支持实时通信技术，Google希望开发社区能够在自己的应用中集成该功能，从而削弱其他对手。</p>
<p>这已经不是Google第一次大方地开源关键项目。去年，Google曾经将VP8视频编解码项目开源，以支持HTML 5技术中的视频媒体播放。如今，多种主流浏览器都已经支持VP8格式，成为主要的多媒体格式，相比伴随着专利、付费纠纷的H.264，开放、免费的VP8更让浏览器厂商放心。</p>
<p>这次WebRTC的开源会对浏览器厂商和实时通信技术领域带来哪些影响，InfoQ中文站将持续关注和及时报道，也欢迎读者朋友发表自己的看法。</p>
<p id="lastElm"></p></div>
<p style="padding-bottom: 0px; widows: 2; text-transform: none; background-color: rgb(255,255,255); list-style-type: none; margin-top: 5px; text-indent: 0px; padding-left: 0px; padding-right: 0px; font: 12px/19px Lucida, 'Lucida Grande', Tahoma, sans-serif; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(115,115,115); word-spacing: 0px; padding-top: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" class="miniBio"><strong><a style="padding-bottom: 0px; padding-left: 2px; padding-right: 2px; color: rgb(28,73,123) !important; text-decoration: none; padding-top: 0px" class="editorlink f_taxonomyEditor" href="http://www.infoq.com/cn/author/%E5%B4%94%E5%BA%B7">崔康</a><span class="Apple-converted-space">&nbsp;</span></strong>热情的技术探索者，资深软件工程师，InfoQ编辑，从事企业级Web应用的相关工作，关注性能优化、Web技术、浏览器等领域。</p><br class="Apple-interchange-newline" /></div><img src ="http://www.cppblog.com/tx7do/aggbug/193776.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2012-10-24 14:26 <a href="http://www.cppblog.com/tx7do/archive/2012/10/24/193776.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>