对于智能手机/手表等设备来说,续航能力/功耗是其重要的指标之一。要想有好的续航能力,一定要把主要应用场景下的功耗优化好。音乐播放就是主要的应用场景之一。本文就讲讲我开发的一款智能手表上音乐播放场景下是怎么做功耗优化的。
功耗优化一定程度上与硬件相关,因此先给出这款智能手表跟音乐播放相关的硬件框图,如图1。

图 1
这款智能手表的SoC为了降成本,把codec芯片和蓝牙芯片都集成到一起,即codec芯片和蓝牙芯片内置了。从上图看出,音乐播放涉及到3个core,分别是AP、ADSP和BTDM(BT Dual Mode,双模BT芯片),各个core之间通过IPC通信。AP上就是播放音乐的应用程序以及audio HAL等,来控制音乐的播放。ADSP上主要做音乐码流的解码以及音效等。ADSP以及内置的codec和SRAM组成了audio子系统。由于是手表,没有有线耳机,使用codec时声音只从扬声器出。当播放蓝牙音乐时就会涉及到BTDM,把SBC码流通过空口发给蓝牙耳机播放出来。
智能手表上音乐播放又分两种场景,一种是声音从扬声器出,一种是声音从蓝牙耳机出。不同场景下的data path是不一样的,功耗的优化方法也会有所差异。先给出这两种场景优化前的data path。
图2是声音从扬声器出的data path。

图 2
从上图看出,音频流从AP发给ADSP,经解码和音效等模块后再送给codec,从扬声器播放出来。
图3是声音从蓝牙耳机出的data path。

图 3
从上图看出,音频流从AP发给ADSP,做完解码和音效等后还要做蓝牙的SBC编码,得到SBC码流,再把SBC码流送给AP上的BT Host。BT Host上做A2DP相关的处理,然后把码流送给BTDM上的BT Controller。BT Controller通过空口把码流发给蓝牙耳机播放出来。
下面开始讲怎么做功耗优化。主要包括如下几点:
1,优化音乐解码算法(如MP3)、SBC编码算法以及音效等算法,来降低MIPS,使它们处理完一帧数据用更少的时间。在一个loop里ADSP少量时间干活,多数时间是处于等待WFI(wait for interrupt)的idle状态。ADSP干活时间越少,功耗越低。以一个loop 10ms为例,先前算法处理需要2ms,其他处理需要1ms, 因此干活3ms, idle 7ms。算法优化后处理只需1ms,ADSP干活时间就变成了2ms, idle变成了8ms。这样就能降低ADSP上的功耗。
2,优化memory布局。音乐播放用到的memory包括AP上的DDR(ASIC设计时就要求ADSP能访问AP的DDR),ADSP上的ITCM和DTCM,以及audio子系统上的SRAM。DDR和audio SRAM上既可以放code也可以放data,ITCM上放code,DTCM上放data。为了降功耗,主要场景下的code和data都不能放在外部的DDR上,而要放在ITCM/DTCM和audio SRAM上。因为内部memory有限,次要场景(如录音)的code和data就要放在外部的DDR上。因此要按照这个原则调整memory布局。同时需要两块share memory(要设成uncache属性)来放AP发给ADSP的音乐码流以及蓝牙音乐时ADSP发给AP的SBC码流。AP跟ADSP之间是IPC通信,发IPC时告诉对方放码流的memory起始地址和大小,对方从告诉的地址上去取就可以拿到想要的数据了。这两块share memory先前是放在DDR上的,要改成放在audio SRAM上。通过优化memory布局,播放音乐时不需要外部的DDR参与,来加快速度从而降低功耗。
3,增大AP每次发给ADSP的音乐流的大小。先前每次只给4k, 这样AP给数据很频繁,导致AP不能长时间的睡下去。要想降低功耗,AP要睡的时间长,因此要把每次发给ADSP的音乐流大小变大。理论上是越大越好,播放一首歌,AP只发一次音乐流,之后AP一直睡下去,这样功耗最小。但这样很浪费memory,需要audio SRAM变很大。所以要折中,取一个功耗上和memory都可以接受的值。
4,当播放蓝牙音乐时,即使用了前面的一二三点,AP也不能长时间的睡下去,因为BT Host模块在AP上,它要周期性的接收从ADSP发过来的SBC码流,做A2DP等处理后再通过IPC送给BT Controller。要想AP长时间睡下去,有必要把BT Host里A2DP相关的放到ADSP上去运行(也可以叫做A2DP offload)。ADSP做完SBC编码后再做A2DP相关处理,然后通过IPC直接把数据发给BT Controller。这样播放蓝牙音乐时的data path就变成了图4。

图 4
把架构做了这样的改动后,ADSP就可以与BTDM直接交互数据,从而可以让AP睡的时间更长一些。这样可以明显降低播放蓝牙音乐时的功耗。
5,当用扬声器播放音乐时,需要对codec的音频同路进行配置。配置时要确保只配置DAC方向上的。如果不小心打开了ADC方向上的音频同路,虽然音乐播放场景下用不到,用户也感知不到,但是会增加功耗的。
经过以上的几点优化后,不管是用扬声器播放音乐,还是播放蓝牙音乐,功耗都会有明显的下降。