« March 2007 | Main | May 2007 »

April 28, 2007

终于不用 VC 了

最近一年半做的主要项目是跨平台的。但是只是说说,还没真的去试着在别的平台上 run 起来。因为我们做的是二进制复用,目标模块文件是自定义格式,所以也不太在乎编译器。原计划是在 Windows 下开发,用 VC 编译的。

最近几天真正开始做跨平台了,想来想去,还是改用 gcc 的好 。废弃 VC 倒不是因为它不好,而是想买一台 Mac mini 放在家里用用 :D 一直家里都没买电脑,我也不用笔记本,回家就是打游戏和睡觉。到时候有了机器,在 Mac OS 上自然是没有 VC 用了。

所以,我的跨平台目标就定在了 win32 、freebsd 、linux 和 macosx 。当然,目前我的测试环境只有 win32 和 freebsd ,这几天就在把这两个搞定。

原来的 build 工具是用的 bjam ,这个是 05 年之初选定的。前段时间反省了一下,又考察了最近两年新出的一些 build 工具后,最后还是决定改回 gmake 。到了今天,我在 windows 下的开发环境就成了 gcc(mingw) + gmake + insight

今天主要是试了下 insight ,这个 gdb 的图形外壳还是很好用的。唯一美中不足的是:我在注册表 HKEYLOCALMACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug 中把它定为默认调试器后,似乎总不太对劲。 gdb 在 attach 到被调试进程上时老是不正确。反正不能正常工作,也定位不了 source code 。但如果直接用 insight 启动程序则可以顺利调试。

前两天则一直在折腾 gmake ,也是件很痛苦的事情。被折磨了几天后,我放弃了一开始就写出一个通用的 Makefile 模板,打算随着项目进展一点点改进。

gcc 倒是这半年一直在 freebsd 下用,只是用的不够深入。今天想把原来用 vc 编译的东西移植到 mingw 时,就好好研究了一下 gcc 的各种选项。对比 VC 的选项,gcc 要丰富和严谨的多。以前 vc 的命令行用的挺熟,一下子换到 gcc 还是有一点点不适应。

最后,留个自己的一个大工程:打算把项目已有的 C++ 代码全部拿 C 改写一遍。没办法啊,我又爱上 C 了 :D 谁叫我精力旺盛呢。

April 24, 2007

古琴和调音器

最近迷上了七弦琴。

一开始是被一个同事忽悠的,她弹了好几年了。只因为一句话,她说:“我喜欢曹子建的《高风亮节》,弹奏的时候,两千年前的人的心情仿佛穿越了时空,你可以在自己身上感受到。”

古琴是君子乐器,排在琴棋书画之首是很有道理的。笑傲江湖中那本被很多武林人士当作天书般武功秘籍的琴谱,其实就是用减字方法记录的琴曲的弹奏指法。琴谱上甚至没有标记节拍和每个音的长短,全凭演奏人的发挥。音乐往往可以比语言更能传达人的感情。心中有什么事情,一抚琴就能安静下来,声音从琴弦中弹出。旁人从琴声中听出弦外之音来,当不是什么难事。

琴谱上也没有标记音高,所以很适合我这种不识五线谱的人来学。而且键盘敲了二十多年,手指头还是满灵活的。琴的声音也极小,半夜练习,隔了堵墙,那幽幽的时断时续的声音就传不出去了。在家练习永远不会被邻居投诉到物业去。

前段时间跟老丁聊起这个,碰巧他认识一个朋友的朋友是制琴的。马上发短信跟人订了一把。因为价格不菲,所以我也算被逼上梁山了 :D 上周末去取了琴来,第一天就是调音。花了一晚上才调好,全靠耳朵听的,似乎还比较准。买的这把琴音色也真是不错,我那同事的说法是,跟她家的那把不可同日而语。

跟着我也就练了一个星期。

主要是看李祥霆老师的教学 VCD ,练一些基本指法。平均每天都玩上两小时。多的时候四、五小时,基本除了编程序,别的时间都花在上面了。

前几天听另一个玩古筝的同事的介绍,去网上买了个调音器,据说定音不准的话,琴声会大打折扣的。买了后才想起来,不就是个音频采样分析的玩意吗?用个麦克风,写个程序分析声音采样的数据,就可以得到准确的音高了,有计算机的话,实在不需要专门的硬件。网上一搜,果然这种软件一大把 :) 可以找不到 palm 版的,不然直接用我的手机做调音器了。

不过今天货寄到了,毕竟能比计算机上装个软件用起来来的方便。花了一晚上校对了一下前段时间靠耳朵调的琴。发现音阶基本是对的,但是基本音低了两度半。怪不得我听起来跟网上找到的视频中的感觉不对。可能是新琴弦太紧,不敢太用力拧,担心弦断掉了。

这回有仪器慢慢的调放心多了,仔细调整好后,发现声色果然不同。弦紧了后,声音更为干净。泛音比我原来弹的时候清晰很多,而且余味悠长。有仪器后,直接散拨每根弦就可以校准了。稍微一点松紧,人耳完全不可能分辨出来的,在调音器上看的非常明显。靠人耳的就不能这么简单了,需要在不同弦的不同徽位弹出泛音来比较,基本上的原理就是让误差扩大大到人耳可以轻易分辨的范围。可惜这样只能让每根弦的相对音高正确,而决定不了基本音高。像我这样没啥音乐感,平时连流行乐都不听的人,不靠仪器只能束手无策了。

最后,虽然被行家知道了要骂的。我的第一首试弹的曲子是首现代曲。也就是黄沾的《沧海一声笑》。不过也是古曲的风格,比如没有 4 这个音。真是神作啊,起头非常简单,顺着拨弦就可以了,听着却很有味道。后来正正规规的练习据说是入门曲的《秋风词》,对我来说还是难了点。网上找了段人家弹奏的视频看,自己却怎么都弹不出那个感觉来,看来路还遥远着呢。

April 19, 2007

修正了 jpeg 解码器中的一个 bug

我一直喜欢重写代码,唯一写了一次就没再重写的是大学时做的 jpeg decoder ,因为它的大量代码都是汇编写的。想来这段代码已经用了快八年了。渗透到公司的各个项目中。

一直以来,总有同事反应这个 decoder 有点小问题,有些看起来正确的图片,解码会出错。但是换一个图像处理软件重新压缩一遍又好了。

我一直没太在意,直到今天问题又被发现了一次。这次一咬牙,调试吧。

结果只花了不到半个小时就找到了问题,而且是一个超级弱智的 bug 。真想打自己一耳光,当初居然这种错误也能犯。修正完以后急忙通知各个项目的代码仓库负责人,想来这套库的很多分支版本里都存在相同的问题了。

April 18, 2007

以自定义方式加载 lua 模块

今天我们的一个小项目开始做内部测试发布前的资源打包。这个项目基本上是用 lua 做开发的。整个开发过程中,我们的代码是直接把 Lua 源代码放在项目的发布目录下的。发布版因为安全或是整洁等种种原因,我们必须给所有的脚本代码打包。

这种事情以前在大话2 里也干过,当时用的 lua 4.0 而且也没多少经验,我们是直接去修改的 lua 的代码,适应我们的打包格式。这次,不想这么干了。希望能够完全不动 lua 官方发布的源代码,来最终完成这项工作。

简单分析了一下,发现实现起来非常简单:

从 Lua 5.1 以后,Lua 有了标准的模块管理库。所以所有的模块加载都是通过 require 来完成。 require 的设计是颇具扩展性的,它会从若干个定义好的 loader 中逐个尝试加载新的模块。系统库中提供了四个 loader ,分别实现已加载模块,Lua 模块,和 C 扩展模块(用了两个 loader 来实现 C 扩展模块的加载)。这些 loader 以 CFunction 的形式放在 require 的环境中的一个 table 里。

如果我们想改变 lua 模块的加载形式,只需要替换或增加一个新的 loader 就可以了。

要做的只需要模仿 loadlib.c 中的 loader_Lua 函数做一个自己的实现,比如在我们的项目中,就允许从自定义格式数据包中,加载一个被加密过的 Lua 代码文件。然后写几行 C 代码,获得 require 的环境(使用 lua_getfenv ),然后取出其中 "loaders" 这个 table ,把新的自定义 loader 插入到 index 2 的地方。

具体的代码就不详述了,仔细阅读一下 ll_require 的实现(在 loadlib.c 中)就很容易明白。我们的整个工作从分析到实现没有超过两个小时,这真是得益于 Lua 良好的设计啊 :D 甚至如果你想从一个网络连接的数据流中加载 Lua 模块,或是通过 http/ftp 协议下载,也是行的通的吧。

April 15, 2007

君子之交淡如水

年少的时候,觉得朋友是世间最重要的东西。与人相交当情同手足、肝胆相照。小学毕业后几年,我还组织过小学同学聚会,看望老师等等。一直到后来上大学了,以往的中学同学还经常聚会,很多次都是我来组织的。大学以前,朋友圈子几乎就是同学圈子,我在方圆十里的圈子里生活了十多年。

后来离开了家,有了互联网,朋友交际圈子大了许多。每到假期,就把足迹遍际全国,四处拜访网友。那时候感觉,交朋友只需要志趣相投。每每碰到知己,便知无不言,言无不尽。促膝长谈那是常有的事。近年来颇为流行人脉这个词,想必我在行业里的人脉,就是那时候起一点点积累下来的吧。

庄子说:“君子之交淡如水”。起初一直不理解。翻开大学毕业时的同学留言册,“性情中人”,这是室友对我的评价。在那时的我来看,好友知己当如美酒,年头越久就越醇香。朋友间自然不计较金钱、无所谓利益,但感情怎么可以用平淡如水来形容呢?

直到后来长大了,渐渐明白了一点道理。

视金钱如粪土者,心中依然有个“利”字。舍弃利益,成就感情,并不算特别高尚的事情。只不过每个人看中的东西不同罢了。予人的是否金钱并不重要,关键在于“舍”这个行为。

在不用为生存问题发愁以后,我最宝贵的东西是时间。上天给了每个人公平的时间,即使你可以全部自由支配它们,时间也总有个上限。对人热情似火:经常聊个天,通个电话,吃顿饭,即使没什么功利,那么也是用时间增进情感了。有意为之也好,随意为之也罢,只是感情贵在交心,无关舍予。

君子群而不党。人与人相处,合群的人们之间在于共同的理想。相互之间可以有爱好、个性的区别,但是却能深刻的理解。不用时刻惦记、勿需礼尚往来,平淡如水,却在内心交融。知己当如是。

最近经历许多事情,也看了不少书。本以为自己已经想明白人生的诸多困惑,结果发现最终自己还是站到了原点。自己依旧是十年前的自己。前几天郁闷的时候给十多年前的老同学发了几条短信,是高中时“同桌的你”。一直感情很好,但很久不联系了。似乎上次见面是出差时去她家做客吃了顿便饭,饭后好象还和她老公聊过魔兽世界,记不太清了。短信没写几行,看着天色已晚,就加了一句“睡吧,没什么事了”。

手机震动了一下,收到简短一句,“有事打电话给我”。刹那间,莫名其妙的泪流满面。

April 13, 2007

张筑生教授的《数学分析新讲》

最近想重新补习一下高等数学,起因是这样的:我老觉得自己对这个世界的认识总是很肤浅,这几天晚上都在读爱因斯坦的《相对论的意义》。其实这本书已经在床头放了小半年了,反反复复的翻了几遍。每每觉得看懂了,第二天想跟人讲心得的时候又觉得自己没全弄明白。

高中时看老爸留下来的物理教材学相对论觉得很新鲜,记住了点概念;大学时听老师讲相对论,背了几个公式;毕业这么多年,挖出点兴趣来再看,觉得自己啥都没明白 :( 。小的时候读《时间简史》,号称全书只有一个数学公式 E=mc2 ,读起来就不枯燥;今天再读的时候,就是想弄清楚公式背后的含义,多一点公式也觉得必要了。只是发现自己的数学掌握的实在不好。那么补数学吧 :D

同事 soloist 推荐了张筑生教授的《数学分析新讲》。

我的家中有三套高等数学的书:一套老爸当年上学留下来的;两套自己读大学时学校让买的,不同的出版社,不同的作者。是谁编的我已经毫无印象了。想来上学时太小,只懂得读书,不晓得识人吧。如今明白了书是人写的这个道理,读书也是识人。

张筑生教授的《数学分析新讲》一定是本好书,因为张教授是个令人尊敬的人 。虽然他的一生只写了三本书,但只此一本就可以让后人记住他。

在网上读到书的后记,“从编写教学改革实验讲义到整理成书,前后花费了五年时间。明知是‘吃力不讨好’,却硬着头皮做了……《红楼梦》里有两句诗:都云作者痴,谁解其中味?”。我下了订单,估计不久就可以拿到吧。

April 11, 2007

Google 为什么不做 Ajax 版的输入法

最近 Google 拼音和搜狗拼音充斥着各个 Blog ,我一点也不关心这些。正如前几天说的,我还是用我的智能 ABC ,直到有输入法也把形码做进去。

今天想到的是,Google 有这么多产品了,比如 Gmail ,Google 日历,Google 文档,Google 表格…… 这些都是需要输入的啊。为什么就不容易做个 ajax 版的可选输入法呢。这样在 Windows 和 Linux 甚至更多平台上的输入习惯就一样啦。感觉会很方便的。

在线输入法也不是没人做过,但是我想 Google 做会不太一样的吧。

April 04, 2007

Google 输入法

今天早上一开电脑,IM 上从世界各地传来的消息是:谷歌 总算出输入法了。(可以点这里放心下载安装,这个文件有 google 的数字签名,不可能被植入第三方软件。)

我一点都不意外。它有一个意料之中的功能:用户自己的输入习惯(可能包括词频分布和自造词)可以被上传到 gmail 帐户。这一定是最吸引人的特性之一,我的一个同事就是因为类似理由爱上了 Google Reader

我爱 Google ,但不盲目的爱。试用了一下,还是舍不得智能 ABC 。但我希望能联系到 Google 输入法的作者(因为我相信这个产品不会是一个庞大的团队在开发),帮助他改进,在我的印象中,google 的人应该是即听的进意见,又有能力即时去做事。我想这点会跟我们的网易 popo 组不同,他们则是听的进意见,但不去做 :)

智能 ABC 是那么好的一个输入法,就是程序实现的不太好。能熟练使用,且正确实现的话,何必需要微软拼音、紫光拼音、拼音++ ……

智能 ABC 我是从 DOS 时代开始用的,原本的版本比现在 Windows 下的丰富许多。主要在于形码部分被删除了,事实证明这个功能的删减无伤大雅,因为最终留下来的特有部分居然也没能被大多数人认识。我认识很多人用 ABC 只是缘于自造词方便,甚至只是输入成语方便而已。

这里要说的智能 ABC 输入法中的两点,他们可以极大的方便单字定位。

其一是两个中括号的功能:[ 可以选择输入词的首字,而 ] 则选择末字。这在输入单字时相当便捷。比如,“衣”这个字同音字太多,我们可以输入 yinfu[ 来准确输入这个字。(意思是衣服这个词的第一个字)。其实,很多人也是敲出词来再删除不要的字来达到这一点的,但我后面会引伸这个应用,来展示其重要性。

其二是笔画码:1 2 3 4 5 表示横竖撇捺折随着手机的普及,早以为众人所熟知。其实这个对于汉字笔形来说是不够且浪费的。在 ABC 中定义了 8 种字形,分别是 6 表示弯(逆时针的折)、7 表示交叉、8表示方框。在拼音后追加笔形,可以极大的减少单字重码率,这是无庸质疑的。还是上面关于“衣”这个例子,用 yi41 或者 yi4f[ 输入,都非常准确。

智能 ABC 里还有一些细节就不一一赘述了,把输入法切入,鼠标右键菜单上选帮助可以得到非常详尽的解说。

虽然我们日常输入汉字的时候是以词来输入,智能化选词和自动造词的功能强化固然是重要的发展方向;但我们做输入法时绝对不能忽视单字输入的准确性。除了输入姓名之外,在第一次制造新词时,这种需求尤其强烈。如果不能方便的定位单字,我们不得不在大量同音字中反复选择需要的单字。这个时候,甚至不能再使用输入一个词再退格的方法了。需要眼睛反馈的方向键选字定位法是多么的不方便,我相信每个用音码作主要输入手段的人都有体会。这种时候,人们需要的不是更短的编码方案,而是尽量少重码且方便记忆的编码定义。我知道 google 拼音中可以以 u 开头输入一些纯笔画码来确定单字,但这远远不够。

另外,汉字中的同音字很多,甚至同音词都不少。传统的拼音输入法其实是一个一对多的关系。即一个拼音编码方案对应多个结果。比如 yifu 可以对应“衣服”也可以是“依附”。实际上,我更希望输入法在储存数据时存在多对多的关系,也就是说,每个词都有多种编码来参与用户习惯的记录。例如 yf 优先匹配“应付”、yif 优先匹配 “衣服”、yifu 则优先匹配“依附”…… 这个似乎正是我现在手机中安装的“掌易”的策略。随着输入法系统对用户习惯的适应,手感会越来越好。

如果认可这种方式,那么加入少量笔画码可以极大的丰富每个单字的编码方式。没有笔画码的时候,只有声母、全拼两种,对于双字词,一共是四种组合方案。即使加入一个笔形编码,双字词也会有八种表示方案。解决大多数重码问题已经绰绰有余了。