会员
周边
新闻
博问
闪存
众包
赞助商
Chat2DB
所有博客
当前博客
我的博客
我的园子
账号设置
会员中心
简洁模式
...
退出登录
注册
登录
Qidi_Huang
博客园
首页
新随笔
联系
订阅
管理
2025年11月17日
生成用于验证 TDM slot 配置的波形
摘要: 使用逻辑分析仪测量 TDM 的 BCLK、FSYNC、SDO引脚上的信号,可以验证 TDM slot 配置及输出是否正确。不过,我们不能使用常规正弦波进行测量,而是要使用一种特殊波形。在这种波形上:有信号的 slot 输出 0xAA;无信号的 slot 输出 0x00。两种 slot 交替,即可在逻辑分析仪上分辨出 slot 个数和宽度。
阅读全文
posted @ 2025-11-17 15:14 Qidi_Huang
阅读(8)
评论(0)
推荐(0)
2025年11月1日
不使用 AAudio 的前提下,降低 Android 音频传输延时的方案
摘要: 如果芯片厂未实现 MMAP 驱动接口,那么即使客户端代码调用了 AAudio 接口,也无法降低音频传输延时。因为 AAudio 会回退到以 legacy 模式工作。在芯片驱动不支持使用 AAudio 的前提下,我们可以通过其它方式来减少音频传输延时。在 native 层实现一个中间件,向上对 priv-app 或 java-service 提供 AIDL 服务接口;向下通过 DeviceHalAidl 打开 StreamHalAidl 来向/从 AudioHAL 写入/读取音频数据。以此绕过 AudioTrack 和 AudioFlinger 部分的延时。
阅读全文
posted @ 2025-11-01 16:44 Qidi_Huang
阅读(43)
评论(0)
推荐(0)
2025年10月29日
替换 Android APEX 包中的动态库的方法
摘要: 先确定要替换的库属于哪个 APEX 包,再替换库文件所属的整个 APEX 包。只单独替换 APEX 包下的库文件,会导致系统无法启动。
阅读全文
posted @ 2025-10-29 14:27 Qidi_Huang
阅读(28)
评论(0)
推荐(0)
2025年9月18日
使用 libaudioclient 实现 Android Native层 音频测试工具
摘要: libaudioclient 除了支持 setAudioPortConfig() 调用,也支持 setMasterMute()、setStreamMute()、setParameters()、getParameters()、setMode() 等接口调用,满足各种开发测试需求。它让你不需要关注这些细枝末节的差别,一份代码可以不加修改地完美运行在不同芯片平台、不同 Android 版本上。尽管 IHalAdapterVendorExtension 被注册为 AIDL service,但这段代码没有通过 binder 去获取服务,而是通过链接 IHalAdapterVendorExtension 实现端的库,直接在代码里构造了 mHalAdapterVendorExtn 对象,以避免不必要的跨进程通信开销。
阅读全文
posted @ 2025-09-18 19:25 Qidi_Huang
阅读(72)
评论(0)
推荐(0)
2025年8月30日
Android 系统中查看进程的物理内存真实占用的方法
摘要: Android 系统提供一款专有工具 procrank 用于查看各进程(包括 Java 进程)的内存占用情况。进程的 Pss 值可以较为准确地反映其真实占用的物理内存大小。 procrank 显示的是所有进程的内存占用概要情况。如果要查看某个特定进程的内存占用情况,可以使用 showmap 命令。
阅读全文
posted @ 2025-08-30 15:01 Qidi_Huang
阅读(149)
评论(0)
推荐(0)
2025年8月7日
基于 Android 16 实现 2声道或多声道录音的方法
摘要: 可以使用 Builder,通过 setChannelIndexMask() 方法来设置声道参数,达到多声道录音的目的。不过,由于前述 1.2节 中的限制,我们在构造 AudioRecord 对象时,不可以使用 getMinBufferSize() 来计算 bufferSize 参数值,而应该手动计算出合适的值。否则,APP 将抛出异常并中止运行。
阅读全文
posted @ 2025-08-07 18:02 Qidi_Huang
阅读(322)
评论(0)
推荐(0)
2025年7月9日
Android 14 为优化 TimeCheck 问题做的 Audio Frameworks 设计变更
摘要: Android 14 会先构造好 AudioFlinger 和 AudioPolicyService 这两个实例,再调用 addService() 依次向 ServiceManager 注册服务。 从提交记录和代码注释看,做这个调整的目的是为了减少 TimeCheck 超时导致 audioserver 进程退出的问题。 修改了 AudioSystem::get_audio_flinger() 逻辑。当 AudioFlinger 调用方与 AudioFlinger 处于同一进程时,就直接返回 AudioSystem 中缓存的 gLocalAudioFlinger,而不再通过 ServiceManager 查询。
阅读全文
posted @ 2025-07-09 17:48 Qidi_Huang
阅读(149)
评论(0)
推荐(0)
2025年6月26日
使用 bootchart 和 perfetto 分析 Android 开机性能
摘要: 从 bootchart.png 图中我们可以看出以下信息: 各主要系统进程是否及时启动; CPU 和 磁盘 在开机过程中的整体负载情况; 某进程的启动时机是否晚于预期; 某进程启动时的 CPU 消耗、忙闲情况; 某进程在开机过程中是否存在崩溃、重启; 如果进程A的功能依赖于进程B,进程B是否及时启动; launcher 进程的启动时机(意味着用户可以触屏操作)。 使用 perfetto 分析过系统运行时性能问题的朋友,应该对这个画风比较熟悉。
阅读全文
posted @ 2025-06-26 18:31 Qidi_Huang
阅读(746)
评论(0)
推荐(0)
2025年6月17日
实现 cout 命令从而快速跳转到 Android 编译产物目录
摘要: 很多时候我们都是执行 cd $OUT 命令来跳转到编译产物目录。然而这个命令既包含特殊字符,又要进行大小写切换,手敲起来费时且不方便,不如自己实现一个 cout 命令来提高效率。做法很简单,我们知道 croot 的实现代码在 /build/envsetup.sh 脚本中,所以我们只需要在其中相邻位置添加以下函数就行了。
阅读全文
posted @ 2025-06-17 18:06 Qidi_Huang
阅读(28)
评论(0)
推荐(0)
2025年6月13日
使用 sysMonApp 分析 Qualcomm Hexagon DSP 性能/负载情况
摘要: 抓取 DSP 整体性能/负载数据: sysMonAppQNX profiler --q6 adsp --duration 60 抓取各硬件线程性能/负载数据: sysMonAppQNX tlp --profile 1 --samplingPeriod 1 --q6 adsp --defaultSetEnable 3 --duration 60 需要将抓取到的数据,即 sysmon*.bin,转换成 HTML 页面,才能阅读。 工作中碰到个 “播放收音机的过程中频繁切换音效导致播放出现大量噪声” 的问题。由于收音机数据是 ADSP 直接从 Modem芯片 读取、再写入功放芯片,所以怀疑噪声是由于 ADSP 性能不足所致,与 CPU 调度无关。以此问题为例,对分析报告过程进行说明。
阅读全文
posted @ 2025-06-13 18:02 Qidi_Huang
阅读(973)
评论(0)
推荐(0)
2025年6月10日
DSP/CPU 性能/算力评估指标介绍
摘要: MPPS 参数有两种用法: 一是用作评估 DSP 最大处理能力。 比如,DSP 主频 1.5GHz,运行其上的代码的平均 CPP 为 3,那么在此种情形下 DSP 能承载的最大 MPPS 就是 500。 二是用作评估代码对 DSP 带来的负载。 因为代码在编译后生成的指令数是固定的,相应地,其 Packet数量 和 CPP 也能预估出来,因而也能估算出代码所需的 MPPS 值。 根据 Qualcomm 建议,车机设备上所有用户场景带来的负载总和不应超过最大 MPPS 的 70%,以避免音频播放时出现噪声。 当 DSP/CPU 的空闲算力不小于所需理论算力的 1.3 倍时,我们才认为 DSP/CPU 能够满足算法模块的算力需求,这是因为需要给算法模块加载/销毁、I/O延迟等非理想情况留出余量。当 DSP/CPU 的空闲带宽不小于该理论带宽值的 1.3 倍时,我们才认为 DSP/CPU 能够满足算法模块的带宽需求。 类似 MPPS,MIPS 参数也常被用来评估 DSP 能力、代码所需负载。
阅读全文
posted @ 2025-06-10 18:11 Qidi_Huang
阅读(780)
评论(0)
推荐(0)
2025年6月4日
新增 AIDL 接口后,高通 QIIFA 编译失败的解决方法
摘要: 高通对某些接口是停用了 QIIFA 检查的。由于我在 vendor 下新增的自定义 AIDL 接口与 AOSP 和 Qualcomm 完全无关,且当前开发阶段我们也没有对接口版本进行冻结的计划,所以我们也可以停用 QIIFA 对该自定义接口的检查,从而解决编译问题。 具体操作为,在 vendor/qcom/proprietary/commonsys-intf/QIIFA-cmd/aidl/qiifa_aidl_skipped_interfaces.json 的 ALL 字段中添加我们的自定义服务名。
阅读全文
posted @ 2025-06-04 17:26 Qidi_Huang
阅读(528)
评论(0)
推荐(0)
2025年5月30日
通过 mDNS 发现和登录局域网内的 Android 设备
摘要: 通常我们会使用两种方法登录 Android 设备: 使用 USB 直接将电脑和 Android 设备相连,然后执行 adb shell 命令登录; 让电脑和 Android 设备连入同一个网络。检查 Android 设备 IP,然后执行 adb connect xxx.xxx.xxx.xxx 和 adb shell 命令登录。 不过这两种方法都存在以下局限性: 要明确知道 Android 设备存在; 要手动配置 Android 设备(连接 USB 线,或查询 IP)。 和我们处于同一局域网上的 Android 设备,只要开启了 USB调试 和 无线ADB连接 功能,我们都可以利用 mDNS 发现它。进而通过 adb 与其建立连接。
阅读全文
posted @ 2025-05-30 15:43 Qidi_Huang
阅读(565)
评论(0)
推荐(0)
2025年5月29日
Android Stable AIDL 编译时绕过 API 版本检查的方法
摘要: 分析编译错误日志,可知 Stable AIDL 是通过比对 hash值 来判断接口变动。回忆在老 Android 版本上开发 HIDL 接口时,可以通过手动修改 hash值 来绕过检查,所以现在我们也尝试这样做来绕过 Stable AIDL 的编译检查。
阅读全文
posted @ 2025-05-29 18:25 Qidi_Huang
阅读(775)
评论(0)
推荐(0)
2023年12月13日
车机 Android 调节音量的三种方式及底层代码逻辑
摘要: 车机环境下的音频使用场景,相较于原始 Android 的音频使用场景,存在这些特殊性: 使用专门的 aDSP 芯片进行音效处理; 需要播放/控制原始 Android 预设之外的音源(AudioUsage); 音源间交互行为更加复杂(AudioFocus); 需要响应更复杂的电源模式变化。 其中第一、二点会直接影响用户从 APP 层调节音量的方式,以及 AudioHAL 的实现。
阅读全文
posted @ 2023-12-13 15:20 Qidi_Huang
阅读(1567)
评论(0)
推荐(1)
2023年12月12日
车机 Android 环境下利用 CarAudioService 实现自定义 Java 服务自启动
摘要: 通过 RO 机制,我们就可以将自己编写的 Java 服务在系统启动时运行起来。
阅读全文
posted @ 2023-12-12 09:51 Qidi_Huang
阅读(580)
评论(0)
推荐(1)
2023年12月11日
通过命令行启用 logcat 日志本地存储功能
摘要: 我们需要一种方式,在不进行界面操作或切换 USB Role 的情况下,也能启用 logcat 日志的本地存储
阅读全文
posted @ 2023-12-11 14:12 Qidi_Huang
阅读(2305)
评论(0)
推荐(1)
2023年10月16日
一种适用于 Android Native 层的代码功能测试框架
摘要: 理想的测试工具代码应该具备以下特点: + 测试流程代码和测试用例代码分离 + 与项目需求相关的代码位于测试用例代码中 + 与项目依赖相关的代码也位于测试用例代码中 + 测试函数接口稳定,函数名及参数不因项目不同而变化 + 测试用例代码可以方便地进行替换
阅读全文
posted @ 2023-10-16 01:27 Qidi_Huang
阅读(141)
评论(0)
推荐(0)
2023年10月15日
使用链表而不是 stdarg 实现可变参数函数
摘要: 为了摆脱 `va_start()` 对参数列表起始地址的依赖,我们可以把函数参数按照从左往右的顺序,依次存储于一个动态创建的链表中。
阅读全文
posted @ 2023-10-15 23:44 Qidi_Huang
阅读(58)
评论(0)
推荐(0)
公告