Android(海思平台)实现HDMI和I2S同时输出音频
本帖最后由 zhaohuarong 于 2017-12-7 17:05 编辑最近工作中需要在Android板上HDMI和I2S(喇叭)做声音切换输出。基本思路就是不使用Android原生的AudioTrack进行声音输出。使用封装的类进行声音的播放,进行两路同时输出,然后切换的时候每次将一个设备设置为静音即可。搞了一个星期才搞定这个事情,写篇文章记录一下,绝对一个字一个字的敲出来的。辛苦啊!
原有的声音播放方式使用的是AudioTrack,专门用于播放声音码流。基本的用法就是不断的去调用AudioTrack.write(byteBuffer, sizeInBytes, AudioTrack.WRITE_BLOCKING);缓冲区中的数据会自动进行播放。但是这个方法无法设置外部声音设备,即无法指定输出设备。
原生的AudioTrack在Android源码中的位置
下面介绍一下实现AudioTrack的write的替代方法,只是可以同时进行双输出。
1.进入厂商的目录下的frameworks目录,可以看见厂商为Android额外增加的一些模块。
2. 我选择将新功能放到hiaudio模块中去。进入hiaudio,我们可以看见该模块的代码结构分类,java中存放该模块面向应用的Java接口,jni中存放的是jni接口,libs中存放的是cpp实现。现在需要按照这个顺序依次将接口从Java层引入到cpp中。
3.打开java目录中的HiAudioManager.java,在该类中添加如下代码
分别表示设置HDMI静音、设置I2S静音、初始化、写入数据。简单的几行代码就定义了在APP中的调用接口。
4.打开jni目录中的cpp文件,该cpp文件为刚才定义的Java接口的jni类型定义,作用相当于一个翻译人员,负责将Java接口翻译成本地化的cpp接口。函数体类调用的都是后面需要实现的cpp接口。
5.下面在进入到libs目录下的虚函数接口类中。在头文件中添加如下声明。
相应的在CPP文件中添加函数体。
6.下面进入到真正的函数执行部分了,上面的步骤都只是为了数据传递,将接口一步一步的向上暴露给Android程序调用,现在我们已经进入Android底层CPP代码。在头文件中添加函数体声明。
然后在CPP中对每个函数进行实现,此时不再是像上面那样固定的编码格式,而是业务逻辑代码。实现具体功能。
这两个函数相对比较简单,直接调用厂商的底层接口即可完成相应的功能。不做过多的介绍了。
初始化函数非常的长,就不全部截图了。目的就是将声音设备初始化,然后绑定到两个物理音频设备上去,这样就可以同时发出声音了。
这个writeData函数是反复调用的,在线音频或者本地音频,通过每次读取固定的长度的内存到缓冲区进行播放。
7.最后一步就是在Android app中调用了。
先import HiAudioManager这个包。这里我播放的是一个音频文件,在线音频码流原理是一样的。
干货!支持! {:10_257:} {:10_266:} 感谢楼主分享 好帖,干货,谢谢楼主
楼主可以私发一下初始化那里的代码吗?我i2s一直没有输出QQ:1091074137谢谢
页:
[1]