我在前面的文章(Android智能手机上的音频浅析)中说过Android手机上有一块专门用于音频处理的DSP,它的特点是频率低(一般几百MHZ)、内部memory小(通常不超过100k word)。要想让Audio DSP上放下更多的内容以及能流畅的运行,要有一些应对措施。今天就聊聊这些措施。

1,频率低的应对措施

由于DSP的频率低,要想软件能流畅的运行,就得把运行时的load降下来。主要的措施有两种,定点化和load优化。先看定点化。

DSP有定点DSP和浮点DSP之分。一般来说,定点DSP具有速度快,功耗低,价格便宜的特点;而浮点DSP则计算精确,动态范围大,速度快,易于编程,功耗大,价格高。音频处理用的DSP通常都是定点DSP。定点DSP,处理定点数据会相当快,但是处理浮点数据就会非常慢。那在定点DSP上涉及到浮点运算怎么办呢?解决方法是浮点运算定点化来节约处理时间,即用定点数表示浮点数。定点数中最高位表示符号位,符号位右边n位表示整数,剩下的表示小数。这种表示方法叫Q格式。

Q格式表示为:Qm.n,表示数据用m比特表示整数部分,n比特表示小数部分,共需要m+n+1位来表示这个数据,多余的一位用作符合位(不表示出来)。例如Q15表示小数部分有15位,一个short型数据,占2个字节,最高位是符号位,后面15位是小数位,表示的范围是:-1<X<0.9999695 。浮点数据转化为Q15,将数据乘以2^15;Q15数据转化为浮点数据,将数据除以2^15。例如假设数据存储空间为2个字节,0.333×2^15=10911=0x2A9F,0.333的所有运算就可以用0x2A9F表示,同理10911×2^(-15)=0.332977294921875,可以看出浮点数据通过Q格式转化后是有误差的。

再看看Q格式的加减乘除基本运算。加减法时须转换成相同的Q格式才能加减。不同Q格式的数据相乘,相当于Q值相加,要右移n位得到正确的值。不同Q格式的数据相除,相当于Q值相减,要左移n位得到正确的值。这里举一个乘的例子:两个小数相乘,0.333*0.414=0.137862

0.333*2^15=10911=0x2A9F,0.414*2^15=13565=0x34FD

short a = 0x2A9F;

short b = 0x34FD;

short c = a * b >> 15;  // 两个Q15格式的数据相乘后为Q30格式数据,因此为了得到Q15的数据结果需要右移15位

这样c的结果是0x11A4=0001000110100100,这个数据同样是Q15格式的,它的小数点假设在第15位左边,即为0.001000110100100=0.1378173828125...和实际结果0.137862差距不大。或者0x11A4 / 2^15 = 0.1378173828125

其他的基本运算就不举例了,网上讲Q格式的有一些文章,感兴趣自己去看。

实际应用中,浮点运算大都时候都是既有整数部分,也有小数部分的。所以要选择一个适当的定标格式才能更好的处理运算。一般用如下两种方法:一是使用适中的定标,既可以表示一定的整数复位也可以表示小数复位,如对于2812的32位系统,使用Q15格式,可表示-65536.0~65535.999969482区间内的数据。二是全部采用小数,这样因为小数之间相乘永远是小数,永远不会溢出。取一个极限最大值(最好使用2的n次幂),转换成x/Max的小数(如果Max是取的2的 n次幂,就可以使用移位代替除法)。刚开始用Q格式时会很别扭,不习惯,用多了就慢慢习惯了。

为了降load,我们在软件开发过程中要做到以下两点:一是选择算法实现时一定要用定点实现。Audio DSP上会运行好多音频处理算法,比如各种codec,这些codec的制定者一般会提供两套reference code,一套定点实现的,一套浮点实现的,我们在选择时一定要选用定点实现的。对于应用在ARM上的音频处理算法,同样是推荐用定点实现的算法,虽然ARM频率高。在ARM上还是要优化算法把load降到尽量低。二是在我们自己的代码中如遇到要做浮点运算(比如算百分比),要用Q格式定点化去算,而不是直接用浮点数去运算。

再来看load优化。我在前面的文章(音频的编解码及其优化方法和经验)中load优化的一些通用方法,在DSP上也适用。不过由于DSP频率低,且DSP上运行的音频处理算法多,有些算法又比较耗load(比如AEC),要想让音频软件流畅的运行,复杂的算法都是要做汇编优化的。做这些不仅专业而且耗时,load优化没有最低只有更低。

2,memory低的应对措施

DSP的内部memory分两种,DTCM(Data Tightly Coupled Memory, 数据紧密耦合存储器)和PTCM(Program Tightly Coupled Memory, 程序紧密耦合存储器)。DTCM用于存data,PTCM用于存code。同时还有外部memory(DDR),它也可存data和code。data和code尽量放内部,因为这样速度快效率高,不到万不得已才将它们放在外部memory上。即使放在外部的也是一些低频访问的data和code,如初始化函数等。今天我们主要讲的是应对DTCM(data memory)小的措施。DTCM主要分以下几个区域:const区、data区、bss区、overlay区。const区顾名思义就是放一些常量的,data区是放已初始化的全局变量和静态变量,bss区是放未初始化的全局变量和静态变量,overlay区主要是根据场景的互斥做一些memory的复用,这是应对memory小的主要措施。我们先看overlay机制。

Overlay机制是指不会同时发生的场景下使用的memory可以复用,在音频上主要有两种情况。一是music使用的memory可以和voice使用的memory复用,因为音乐播放和打电话不可能同时发生。通常是音乐播放时来电话,音乐播放就暂停,把音乐播放的context以及还在buffer中未播放的数据拷贝到外部memory上,把music使用的memory让给voice用。打电话结束后再把放在外部memory上的音乐相关的context以及未播放的数据拷进内部memory原先的位置上,从而继续音乐的播放。二是各种codec使用的memory的复用,因为同时只有一种codec在使用。音乐的decoder有MP3、AAC,播放音乐时只可能有一种decoder在用。Voice的codec有AMR-NB、AMR-WB、EVS,打电话时只可能有一种codec在用。它与第一种的区别是不需要保存上下文。这样可以画出DTCM的分布图,如下图:

上图中memory地址是由低向高增长,分别是const区、data区、bss区、overlay区。在overlay区music和voice有相同的起始地址,在music中decoder MP3和AAC又有相同的起始地址,在voice中codec AMR-NB、AMR-WB和EVS又有相同的起始地址。

对于PTCM,同样可以用overlay机制。不过除非一些代码重写,一般很难省code size了。

除了overlay机制,其他的就要一点一点的抠来省memory了,主要有以下几点:

1) 定义数据类型时能用short的就不要用int

2)在overlay区域,buffer的大小都是指定的。指定时要正确算出大小值,不要指定大了,指定大了就浪费了。

3)在data区或者bss区的buffer要看是不是分大了,比如有的buffer分三块就够了,也就没必要分四块了,分四块一是浪费了buffer,二是有些场景下增加了时延。

4)  DSP上每个thread/task的栈的大小都是指定的。为了省memory,栈的大小不可能很大,一般不超过1k word。这就要求写代码时不能有大的局部变量数组等,遇到时就要通过一些技巧解决。如一个要把双声道的数据从interleave变成non-interleave的函数,写成了如下实现,避免了大的局部变量数组。通常的做法是用一个大的局部变量数组先存右声道数据,最后再一起拷到指定位置上。

void interleave_to_noninterleave(int16_t *buf, int32_t frame_cnt)

{

int i,j;

short temp;

for(i = 1; i < frame_cnt; i++) {

temp = buf[2*i];

for(j = 0; j < i; j++)

buf[2*i - j] = buf[2*i - j -1];

buf[i] = temp;

}

}

5)代码编好后会生成一个各buffer起始地址和大小的文件。关注那些size较大的buffer,分析有没有减小的可能。

总体而言,DSP由于频率低和memory小的限制,在上面写代码比在ARM上要求高些,花的时间长些。长时间在ARM上写代码,转到DSP上会有些不习惯,有个适应过程。

Android手机上Audio DSP频率低 memory小的应对措施的更多相关文章

  1. Android手机上,利用bat脚本模拟用户操作

    ………… 那么你就可以来看看这篇帖子了. 言归正传 利用bat脚本模拟用户操作,需要用到两点: ①就是adb命令了,adb命令可以用来模拟用户在手机上的操作 ②bat语言,就是批处理语言,主要用来进行 ...

  2. 局域网内笔记本分屏到android手机上

    前提 笔记本电脑1台 安卓/ios手机1部 局域网 spacedesk 预览 参考: https://www.appinn.com/spacedesk https://spacedesk.net/de ...

  3. H.264视频在android手机端的解码与播放(转)

    随着无线网络和智能手机的发展,智能手机与人们日常生活联系越来越紧密,娱乐.商务应用.金融应用.交通出行各种功能的软件大批涌现,使得人们的生活丰富多彩.快捷便利,也让它成为人们生活中不可取代的一部分.其 ...

  4. 手机上的ROM与RAM

    ROM:read only memory翻译为只读存储器. RAM:read access memory翻译为随机存储器. 下面是一张手机的配置参数表. 简单来说,RAM就是真正意义上的内存,而ROM ...

  5. React-Native项目在Android真机上调试

    目录 1.确保你的设备已经成功连接.可以终端输入adb devices来查看: 2.终端运行npm start 开启本地服务,成功后运行react-native run-android来在设备上安装并 ...

  6. 华为联运游戏审核驳回:在未安装或需更新HMS Core的手机上,提示安装,点击取消后,游戏卡屏(集成的6.1.0.301版本游戏SDK)

    问题描述 更新游戏SDK到6.1.0.301版本之后,游戏包被审核驳回:在未安装或需更新华为移动服务版本(HMS Core)的手机上,提示安装华为移动服务(HMS Core),点击取消,游戏卡屏.修改 ...

  7. 如何实现桌面App图标可以动态显示消息数(类似手机上的QQ图标)?

    手机上的APP , 像QQ和微信等都可以在图标上动态显示消息数(最大99) , 那么你有没有想过这些效果是如何实现的?桌面上开发的传统应用程序能否也实现类似的功能? 1 思路 桌面快捷方式的图标本质上 ...

  8. Android手游《》斗地主完整的源代码(支持单机和网络对战)

    Android手游<斗地主>完整的源代码(支持单机和网络对战)下载.一个很不错的源代码. 斗地主掌游是一个独特的国内社会斗地主棋牌游戏,之后玩家可以下载网上斗地主和全世界.掌游斗地主特点: ...

  9. Android中的Audio播放:竞争Audio之Audio Focus的应用

    from://http://blog.csdn.net/thl789/article/details/7422931 Android是多任务系统,Audio系统是竞争资源.Android2.2之前,没 ...

随机推荐

  1. Java集合框架源码分析(2)LinkedList

    链表(LinkedList) 数组(array)和数组列表(ArrayList)都有一个重大的缺陷: 从数组的中间位置删除一个元素要付出很大的代价,因为数组中在被删除元素之后的所有元素都要向数组的前端 ...

  2. yii中的restful方式输出并调用接口和判断用户是否登录状态

    //创建一个控制器接口 返回的是restful方式 <?php namespace frontend\controllers; use frontend\models\Fenlei; use f ...

  3. 『TensorFlow』slim模块常用API

    辅助函数 slim.arg_scope() slim.arg_scope可以定义一些函数的默认参数值,在scope内,我们重复用到这些函数时可以不用把所有参数都写一遍,注意它没有tf.variable ...

  4. SpringCloud服务负载均衡实现原理02

  5. django+celery +rabbitmq

    celery是一个python的分布式任务队列框架,支持 分布的 机器/进程/线程的任务调度.采用典型的生产者-消费者模型 包含三部分:1. 队列 broker :可使用redis ,rabbitmq ...

  6. 认识jmeter

    1.jmeter是什么:Apache Jmeter是Apache组织开发的基于java的压力测试工具. Jmeter可用于对服务器.网络或对象模拟巨大的负载,来自不同压力类别下测试他们的强度和分析整体 ...

  7. Redis常用命令与高级应用

    附: 127.0.0.1:6379> set xiaofei 小飞 OK 127.0.0.1:6379> get xiaofei "\xe5\xb0\x8f\xe9\xa3\x9 ...

  8. Java学习笔记42(数据库连接池 druid连接池)

    druid连接池: 是阿里的连接池,druid的稳定性及效率都很高,目前用的比较广,所以建议开发过程中尽量用druid连接池(支持国产最重要) druid连接池也需要配置文件,配置文件必须是prope ...

  9. 产品经理面试题——浅谈O2O

    分析:O2O也要分种类.      现在的O2O 已经是线上线下相互融合的阶段了,无论是线上体验,线下消费还是线下体验,线上下单.都已有比较成熟的模式.我对O2O的理解就是以消费者为中心,整合线上和线 ...

  10. 爬虫案例(js动态生成数据)

    需求:爬取https://www.xuexi.cn/f997e76a890b0e5a053c57b19f468436/018d244441062d8916dd472a4c6a0a0b.html页面中的 ...