首页-无极娱乐_注册
首页-无极娱乐_注册
全站搜索
 
 
新闻详情
 
当前位置
实时Android语音对讲系统架构
作者:管理员    发布于:2022-07-28 20:51    文字:【】【】【
       

  实时Android语音对讲系统架构。本文属于Android局域网内的语音对讲项目系列,《通过UDP广播实现Android局域网Peer Discovering》实现了局域网内的广播及多播通信,本文将重点说明系统架构,音频信号的实时录制、播放及编解码相关技术。

  AudioRecorder和AudioTracker是Android中获取实时音频数据的接口。在网络电话、语音对讲等场景中,由于实时性的要求,不能采用文件传输,因此,MediaRecorder和MediaPlayer就无法使用。

  其中,audioSource表示录音来源,在AudioSource中列举了不同的音频来源,包括:

  sampleRateInHz表示采样频率。音频的采集过程要经过抽样、量化和编码三步。抽样需要关注抽样率。声音是机械波,其特征主要包括频率和振幅(即音调和音量),频率对应时间轴线,振幅对应电平轴线。采样是指间隔固定的时间对波形进行一次记录,采样率就是在1秒内采集样本的次数。量化过程就是用数字表示振幅的过程。编码是一个减少信息量的过程,任何数字音频编码方案都是有损的。PCM编码(脉冲编码调制)是一种保真水平较高的编码方式。在Android平台,44100Hz是唯一目前所有设备都保证支持的采样频率。但比如22050、16000、11025也在大多数设备上得到支持。8000是针对某些低质量的音频通信使用的。

  channelConfig表示音频通道,即选择单声道、双声道等参数。系统提供的选择如下:

  与AudioRecord类似,AudioTrack的构造器方法依然有很多需要选择的参数。其中,streamType表示音频流播放类型,AudioManager中列出了可选的类型如下:

  Speex是一个声音编码格式,目标是用于网络电话、线上广播使用的语音编码,基于CELP(一种语音编码算法)开发,Speex宣称可以免费使用,以BSD授权条款开放源代码。

  Speex是由C语言开发的音频处理库,在Android中使用,需要通过JNI来调用。因此,对NDK开发不熟悉的朋友,可以先了解下文档:向您的项目添加 C 和 C++ 代码。

  完成上述配置之后,正式开始在Android中使用Speex进行音频编解码。主要包括以下步骤:

  这里设置了每帧处理160个short型数据,压缩比为5,每帧输出为28个byte型数据。Speex压缩模式特征如下:

  数据包要经过Record、Encoder、Transmission、Decoder、Play这一链条的处理,这种数据流转就是对讲机核心抽象。鉴于这种场景,本文的实现采用了责任链设计模式。责任链模式属于行为型模式,表征对对象的某种行为。

  创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

  结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

  行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

  责任链设计模式的使用场景:在责任链模式里,很多对象里由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。下面来看下具体的代码:

  以Recorder、Encoder、Sender为例说明输入侧数据的处理(这里仅列出部分代码,具体代码参考github地址):

  Encoder的下一个处理节点是Sender,在Sender的handleRequest()方法中,通过多播(组播),将音频编码数据发送给局域网内的其它设备。

  即:在界面初始化AudioInput对应的线程的时候,就完成这些类的实例化,并指定Recorder的下一个处理者是Encoder,Encoder的下一个处理者是Sender。这样使得整个处理流程非常灵活,比如,如果暂时没有开发编解码的过程,在Encoder的handleRequest()方法中直接指定下一个处理者:

  在Activity中,分别申明输入、输出Runable、线程池对象、界面更新Handler:

  可能有的同学会觉得这里的责任链设计模式用法并非真正的责任链,真正的责任链模式要求一个具体的处理者对象只能在两个行为中选择一个:一是承担责任,而是把责任推给下家。不允许出现某一个具体处理者对象在承担了一部分责任后又把责任向下传的情况。

  本文中责任链设计模式的用法确实不是严格的责任链模式,但学习的目的不就是活学活用吗?

  其中,corePoolSize表示线程池中所保存的核心线程数,包括空闲线程;maximumPoolSize表示池中允许的最大线程数;keepAliveTime表示线程池中的空闲线程所能持续的最长时间;unit表示时间的单位;workQueue表示任务执行前保存任务的队列,仅保存由execute方法提交的Runnable任务;threadFactory表示线程创建的工厂,指定线程的特性,比如前面代码中设置音频播放线程为守护线程;handler表示队列容量满之后的处理方法。

  首先,对于录音线程,由于对讲机用户大部分时间可能是在听,而不是说。录音线程可能长时间不用,应该让其超时回收,所以录音线程宜使用CachedThreadPool;

  其次,对于发现局域网内的其它用户的功能,该功能需要不断循环执行,相当于循环的向局域网内发送心跳信号,因此宜使用ScheduledThreadPool;

  最后,对于音频播放线程,该线程需要一直在后台执行,且播放需要串行执行,因此使用SingleThreadExecutor,并设置为守护线程,在UI线程(主线程是最后一个用户线程)结束之后结束。

  Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...

  Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...

  今天,咱先讲一个故事。 话说,一个商人赚了一大笔钱,正骑着马行驶在归家的途中。离家不远了,这时他的仆人发现马的后掌...

相关推荐
  • POE交换机 4口百兆POE交换机 10100M四口PoE以太网供电
  • 实时Android语音对讲系统架构
  • PoE交换机不供电了要如何处理
  • POE不能供电如何排查
  • 丰润达推出全新24口全千兆网管型PoE交换机
  • TL-SG1005P
  • TL-SG1210P
  • NETGEAR 10G商业网络解决方案
  • 楼宇对讲系统方案设计架构(整理)
  • 楼宇对讲系统结构
  • 脚注信息
    版权所有Copyright(C)2022-2023首页-无极娱乐_注册 txt地图 HTML地图 XML地图
    友情链接: