LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 4289|回复: 20

使stardict 使用alsa 发音

[复制链接]
发表于 2005-11-12 12:35:41 | 显示全部楼层 |阅读模式
使stardict 使用alsa 发音

相信大家都有用星际译王这款软件包吧!
说真的,是真的好用!不过对我来说有一点不爽!
那是发声部分,我用的是alsa,但stardict用的是esd,因此
我每次想让她发声都不得不启动esd这个守护进程。而在我的系统中
几乎只有这一个程序是用esd发声。单单为了它而启动esd我觉得不值
的,于是我就想让她用alsa发音。但星际译王没有这个选择项!所以我只有
改它的源程序来实现了!

如果你也想这样的话就可以往下看了!
道理很简单,星际译王用的是gnome系统的API来发音的,就是gnome_sound_play
来发音的,而它使用的就esd,起码在我的系统上是。(是不是gnome有方法把esd
换成alsa的呢?如果有就不用这么麻烦了!)我们所做的就是自己写个用alsa的发
音函数替换它就行了!就这样而已!
进入源码目录 stardict/src 下,
编辑 readword.h 加入以下我们发音函数的声明

namespace asound
{
        void ao_sound_play(const char * filename);
}
       
在声明一个名字空间asound,里面有一函数。
然后保存。再编辑readword.cpp , 添加以下内容:

#include <unistd.h>
#include <errno.h>

asound::ao_sound_play (const char *filename)
{
  pid_t pid;
  pid = fork ();
  if (-1 == pid)
  {
    perror ("Fork falid to creat a process");
  }
  else if (0 == pid)
  {
    close (0);
    close (1);
    close (2);
  if (execlp ("/usr/bin/aplay","aplay",filename, NULL) < 0)
    {
      perror ("Execl failed");
      exit (1);
     }

    }
}

请注意你系统上aplay命令的路径,如果是其它路径则自行更改execlp
的第一个参数了!
修改完后可以进行下一步了,在readword.cpp文件中找到下面一行:(在文件的结尾处)

gnome_sound_play(filename);
将它注释掉并添加代码,结果如下:

//gnome_sound_play(filename);
asound::ao_sound_play (filename);

保存readword.cpp文件。
依照上面替换代码的方法,把floatwin.cpp, mainwin.cpp, stardict,cpp中的
gnome_sound_play(filename)全替换成asound::ao_sound_play(filename)
然后保存文件退出。(相信替换字符大家都有高效的方法了,为防还是有某些人要
一行行换的话,这里就说说我不成熟的做法,用Vim打开上面据说要改的文件。在
命令模式下执行
:%s/gnome_sound_play/asound::ao_sound_play/g
保存退出)
好,现在可以编译stardict,
./configure &&make &&make install
这时启动stardict就可以听到声音而不用启动esd了!:)

这里做一些说明,以上是在debain 3.1 kernel 2.6.10 gcc 4.0 gnome2.10 stardict2.4.4
环境下测试成功。因为stardict依赖许多gnome的API,因此要编译它要装好些gnome
的库。因此你首先要保证你可以正常编译stardict,如果缺少什么库的话用apt装上
吧!
以上只是提供给一些有这种需要的人一种参考的方法,当然如果你有更好的方法的话
不访告诉我们大家。如果有什么可以放进的地方也可以提出来!欢迎大家讨论!
发表于 2005-11-12 13:02:58 | 显示全部楼层
:s%/gnome_sound_play/asound::ao_sound_play/g

s/s%/%s/

anyway thank you for sharing
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-11-12 13:48:56 | 显示全部楼层
晕!多谢兄弟指出编辑的错误,关于文本替换那一行大家看着办了,在帖子变成了笑脸了。
回复 支持 反对

使用道具 举报

发表于 2005-11-12 13:56:34 | 显示全部楼层
用code包起来,或者用php包起来
回复 支持 反对

使用道具 举报

发表于 2005-11-12 16:26:21 | 显示全部楼层
有一个问题
短时间内会产生很多僵尸
虽然最后会被init回收
不过看着不爽
我做了个补丁
回复 支持 反对

使用道具 举报

发表于 2005-11-12 16:34:37 | 显示全部楼层
主要就是注册了一个SIGCHLD的handler
在里面waitpid
回复 支持 反对

使用道具 举报

发表于 2005-11-12 17:22:20 | 显示全部楼层
刚才那个还是有点问题
如果在输入单词的提示框里输入一个可以发声的单词,并且按住回车不松手的话,还是会产生少量的僵尸
用一个循环就好了
while( waitpid(-1, NULL, WNOHANG) > 0 );

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-11-12 17:28:24 | 显示全部楼层
的确是这样!我当时太急了,加上经验也不多!因此一时没想到处理这个僵死进程的问题!
多谢zhllg兄!
看过zhllg兄的补丁了,很好,测试过偶尔会有几个僵死进程出现!我在那个信号处理
函数里加入个循环,以使它等待所有子进程! 这样更保险一点!:)

void asound::sigchld_handler(int s){
    while(waitpid(-1, NULL, WNOHANG)>0)
            NULL;
}


另多谢zhllg兄的指点!
回复 支持 反对

使用道具 举报

发表于 2005-11-12 17:40:22 | 显示全部楼层
不客气,互相学习,呵呵
回复 支持 反对

使用道具 举报

发表于 2005-11-13 12:18:58 | 显示全部楼层
唉,一群n银
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表