声音冲突处理

  在FM收音机中提到冲突处理,当收音机正在播放时,如果有其他需要播放声音的app启动,这时就会产生冲突事件。如来电,短信铃声,音乐播放,视频播放等。而前面我只是简单的说了下,根据不同的app进行不同的处理,主要是产生冲突的app运行时间来进行考虑。而事件冲突是如何产生,FM收音机怎么知道有冲突事件发生,知道冲突事件后又是如何处理的呢?这些是通过一个声音优先级管理组件来实现的。

  首先所有需要播放声音的app都需要创建这个组件的一个实例,注册自己的优先级处理函数,运用自己的优先级。

  ISHELL_CreateInstance(pThis->a.m_pIShell, SYS_CLSID_IVOICEPRIORITY, (void**)(&pThis->pIVoicePriority));

  优先级管理组件提供了一些函数来管理需要播放声音的app,主要的函数有四个:

  IVoicePriority_RegisterNotify()
  IVoicePriority_UsePriority()
  IVoicePriority_UnusePriority()
  IVoicePriority_UnregisterNotify()

  IVoicePriority_RegisterNotify()函数有一个参数是声音的优先级大小,是定义在一个枚举中的,还有一个是事件处理函数的指针定义如下:
  typedef void (*PFNPriorityNotify)(void* pUser, TPriorityNotifyType NotifyType);

  TPriorityNotifyType也是一个枚举类型,定义了通知事件的类型,
  typedef enum

  {

    PRI_NOTIFY_ACTIVE,
    PRI_NOTIFY_INTERRUPT,

  } TPriorityNotifyType;

  优先级定义

  typedef enum

  {

  ...

  PRIORITY_FMRADIO,

  ...

  PRIORITY_ALARM
  ...
  PRIORITY_CALLINGING,
  PRIORITY_INCOMINGCALL,

  }TVoicePriority;

  枚举中的值越大,优先级越大,中间还有一些其他的app,省略掉了。第一次调用IVoicePriority_RegisterNotify()会创建一个链表,链表中的结点包含了每个app的优先级和冲突事件处理函数,以及一些其他的数据。后来调用IVoicePriority_RegisterNotify()会向链表中插入一个结点,同时会对链表进行排序,排序是通过优先级的大小进行的,是大优先级的结点排在最后面。
  IVoicePriority_UsePriority()首先判断当前app的优先级是否是最大的,是则调用它在链表中前一个结点的事件处理函数,通过向该函数传递一个PRI_NOTIFY_INTERRUPT参数,来通知该app有声音优先级事件。

  IVoicePriority_UnusePriority()和IVoicePriority_UsePriority()一样判断当前app的优先级是否是最大的,是则调用它在链表中前一个结点的事件处理函数,通过向该函数传递一个PRI_NOTIFY_ACTIVE参数,来通知该app有声音优先级事件。
  IVoicePriority_UnregisterNotify()从链表中删除当前app的结点。

  举个例子来说明优先级管理组件是如何来工作的:假如首先打开收音机,这时收音机app会创建优先级管理组件的实例,调用IVoicePriority_RegisterNotify()注册声音优先级事件处理函数,这时链表中保存了一个结点,结点包括FM收音机的优先级大小,以及声音优先级事件处理函数:
  void FMRadio_ICBPriority(void* pUser, TPriorityNotifyType NotifyType)
  {

    if (PRI_NOTIFY_INTERRUPT == NotifyType)

    {

    //暂停或者关闭收音机,以及一些其他处理

    }

    else if (PRI_NOTIFY_ACTIVE == NotifyType)

    {

    //继续播放收音机

    }

  }

  接着FM收音机app调用IVoicePriority_UsePriority(),它首先判断当前app的优先级是否是最大的,这时只有一个app,链表中只有一个结点,所以它没有前一个结点,也就不会调用前一个结点的事件处理函数。
  收音机正在播放时,如果这时闹钟时间到,要播放闹钟声音。闹钟app和FM收音机一样,首先会创建优先级管理组件的实例,调用IVoicePriority_RegisterNotify()注册声音优先级事件处理函数,这时链表已经存在,所以闹钟app向链表中插入一个结点,结点也包含闹钟app的优先级大小,以及事音优先级事件处理函数。
  void Alarm_ICBPriority(void* pUser, TPriorityNotifyType NotifyType)

  {
    if (PRI_NOTIFY_INTERRUPT == NotifyType)

    {
    //暂停或者关闭闹钟声音,以及一些其他处理

    }

    else if (PRI_NOTIFY_ACTIVE == NotifyType)

    {

    //继续播放闹钟声音

    }

  }

  接着闹钟app调用IVoicePriority_UsePriority(),它首先判断自己的优先级是否是最大的,在这里闹钟的优先级比FM收音机大,所以它会调用前一个结点的声音优先级处理函数,也就是FM收音机的声音优先级处理函数,向函数的第二个参数传递PRI_NOTIFY_INTERRUPT,FM收音机这时会暂停,接着闹钟播放声音。闹钟播放完毕之后,闹钟app退出,调用IVoicePriority_UnusePriority()函数,它也首先判断自己的优先级是否是最大,在这里闹钟app的声音优先级是最大,所以它调用前一个结点的声音优先级处理函数,即FM收音机的声音优先级处理函数,并向函数的第二个参数传递PRI_NOTIFY_ACTIVE,这时收音机继续播放,闹钟app继续调用IVoicePriority_UnregisterNotify()把自己的结点从链表中删除,这时收音机成为了优先级最大的结点。

  这里是两个app的情况,多个app也进行类似的处理。注意每一时刻只有一个app能够进行声音播放。通过前面的分析,还可以发现,只有优先级高的app才能打断优先级低的app,任何时刻在播放声音的app一定是优先级最高的,最高优先级的app退出时,会通知优先级仅次于自己的app。上述过程还可通过图表描述如下:

2010082519125193.jpg

转载于:https://www.cnblogs.com/rager/archive/2010/08/25/1808427.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值