现在的位置: 首页 > 综合 > 正文

2012- 16-23

2013年10月27日 ⁄ 综合 ⁄ 共 2672字 ⁄ 字号 评论关闭

1,开始的两天是一头扎入到asterisk的铃音检测算法中,抽取asterisk的dsp处理,对dahdi模块读取到的铃音数据进行算法处理,但是始终令我不解的是asterisk通过Goertzel算法计算出来的能量值与我抽取的代码计算出来的能量值始终差一个数量级,导致我的铃音到语音(也就是对方的摘机事件)的检测一直有问题,仔细跟踪了asterisk的流程,也没用发现特别的情况,于是自己就斗胆更改了dsp处理的门限阀值,这样对铃音和语音的判断就不会出现错误的情况了,总算将这个心头之病勉强解决了。

2,而后测试了asterisk的回音消除,取出asterisk的回音消除的相关函数代码,放到模拟程序中测试,一直报告参数错误。主要我是按照chan_dahdi.conf.sample中的参数配置的,里面我看到有一个echocan = yes,还有一个samplecount的东西,看起来意思是以多大的sample进行回音消除处理,还有三个参数,param1=14,param2=0,param3=128,于是我按照这个对数据将dahdi驱动的回音消除结构体配置好,通过ioctl传入到dahdi驱动中,却一直报参数错误,气死我了。于是看了一下当前使用的配置文件,没有使用param1,param2,param3这三个参数,于是我也就将参数个数设置为0
,将哪个echo_operation结构给传递了进入,这次不报错了。经过测试,效果还可以。由于我现在还没有把完整的电话呼叫流程跑起来,就听筒中一直播放歌曲,然后我同时对着话筒说话,当没有加回音消除的时候,dahdi read下来的数据全是听筒中的歌曲,自己的说话声音几乎听不见,加上回音消除,歌声很多都给过滤掉了,自己感觉不错。由于没有完整的跑这个电话流程,也没有办法进行实际应用场景的测试。

3,测试dahdi板卡用fxs模块直接连接话机的检测事件。挂机和摘机都可以检测到,但是针对dtmf的检测又不行了,时灵时不灵,看来还是需要进行能量分析一下,这个估计比铃音检测要困难一点,主要是涉及的门阀值的判断比较多,有点恶心。

4,测试了linux的锁,信号量,线程,供以后使用

5,周末看了设计模式的三章,其实这个本应该是几年前就该完成的工作,到现在还在拖拖拉拉的,我真是有点无可救药了。

观察者模式:

主要是描述对象间的依赖关系,当一个对象的状态发生改变的时候,所有依赖他的对象都会改变。

 
Subject Observer

virtual void AddObserver(Observer* ob);
virtual  void Update(Subject* s) = 0;

virtual void RemoveObserver(Observer* ob);
protected:

virtual void Notify();
Observer();

List<Observer*> m_listObvservers;

主要的notify方法的实现:

for(Observer ob in m_listObservers)

ob->Update(this);

ConcreteObserver

public:

ConcreteObserver(Subject* s){

m_pSubject = s;

m_pSubject->AddObserver(this);

}

~ConcreateObserver(){

m_pSubject->RemoveObserver(this);

}

void Update(Subject* s){

if(m_pSubject == s){// Got Notice, Do Something......

}

}

private:

Subject* m_pSubject;

这两个类都以虚基类的方式去使用,在Observer的
构造函数中可以传入一个Subject对象,表明观察的目标,


策略模式:

定义一系列的算法,并把它们封装起来,当算法更改的时候,客户程序不需要大改变。简单来说就是抽象和实现相分离。

具体做法:

定义一个抽象基类,它有一个算法接口,再定义具体的子类,实现这些算法接口。对于客户程序只需要持有一个对抽象算法基类的引用就可以了。

当需要调用算法1的时候,就实例化一个算法1的实例,调用算法的抽象接口,需要使用算法2,就实例化算法2。这里面会涉及到传递参数的问题,当在运行算法的时候,需要将客户程序的参数传递到算法中,一个是抽象接口中携带所有的参数,这样为了满足算法1,2,3可能会有冗余参数,一个可以传递一个客户程序自身的对象,由算法自身的实现取出所需要的数据,这种情况客户程序和算法的耦合度就提高了,还有一个通过模板类参数,这个是静态绑定,效率高,不过变通性不好。

针对这个用法,我发现asterisk中的编解码的那个庞大的模块使用的就是这个方式。

模板方法模式:

定义一个算法的骨架,将有一些具体的实现延迟到子类实现。这个在mvc架构中特别常见,像iphone开发中的viewDidLoad,ViewWillAppear都是这样的方法,模板方法一次性实现算法的不变部分,将可变的部分留给子类实现,使用的时好莱坞法则,作为子类,你只需要知道它会被调用什么时候被调用就可以了,而不用太关心到底是怎么调用的。留给子类的实现操作一般有两种,必须实现的抽象操作和可以覆盖的钩子操作。为了避免子类覆盖的时候忘记调用父类的相应操作,可以将这样的操作转换为一个模版方法和一个钩子操作,父类中此钩子操作什么也不做,留给子类去实现。针对抽象操作,建议有一个命名约定。工厂模式经常被模版方法调用,我感觉主要是上层都是抽象的,肯定需要子类实现一个工厂方法才能实现具体操作的。

GOF的总结:模版方法是使用继承来改变代码的一部分(子类覆盖父类的实现),策略模式使用委托来改变整个算法(作为客户程序的一个成员引用)。

asterisk中的ast_channel应该可以称之为模版方法的使用例子,在通话过程中,主要调用的就是chan->tec_pvt->read ,chan->tec_pvt->write操作,相当于上层将通话流程的算法结构已经定义清楚了,具体的channel负责实现具体read和write方法,当然还需要实现一个工厂方法,为了创建一个channel。


稍微吐槽一下,国人的代码质量与国外真的还是有很大差距的,国人有很多小公司,为了生存,利润要迅速出来,要不然就很难维持下去。于是呢,大家写出来的代码就很少考虑架构呀,设计呀,代码质量呀,等等的东西,先出产品卖了钱再说,很是郁闷又无可奈何。

抱歉!评论已关闭.