当前位置: 首页 > news >正文

Android Soundtrigger唤醒相关时序学习梳理

本文所写内容是在高通芯片平台相关代码基础上学习整理汇总,如有描述不当之处,欢迎指正!

1、SoundTrigger注册唤醒监听事件回调流程(SoundTrigger HAL层到ADSP层,不包括FWK层)

//(1)SoundTriggerSession 回调
vendor/qcom/opensource/audio-hal/st-hal/SoundTriggerSession.cpp
void SoundTriggerSession::GetRecognitionCallback(recognition_callback_t *callback)*callback = rec_callback_;//(2)StartRecognition()接口,关联到 callback
int SoundTriggerSession::StartRecognition(const struct sound_trigger_recognition_config *config,recognition_callback_t callback,void *cookie,uint32_t version)rec_callback_ = callback;//(3)在pal_callback()中调用callback()将存放在sound_trigger_recognition_event 中的数据传递fwkint SoundTriggerSession::pal_callback(pal_stream_handle_t *stream_handle,uint32_t event_id,uint32_t *event_data,uint32_t event_size,uint64_t cookie)struct sound_trigger_recognition_event *st_event = nullptr;
recognition_callback_t callback;
session->GetRecognitionCallback(&callback);callback(st_event, session->GetCookie());//(4)在SoundTriggerDevice()中调用SoundTriggerSession::StartRecognition()
vendor/qcom/opensource/audio-hal/st-hal/SoundTriggerDevice.cpp
static int stdev_start_recognition(const struct sound_trigger_hw_device *dev,sound_model_handle_t sound_model_handle,const struct sound_trigger_recognition_config *config,recognition_callback_t callback,void *cookie)ATRACE_BEGIN("sthal: stdev_start_recognition");
status = st_session->StartRecognition(config, callback, cookie, hw_properties_extended.header.version);//(5)在SoundTriggerDevice::Init()中进行接口初始化
int SoundTriggerDevice::Init(hw_device_t **device, const hw_module_t *module)STHAL_DBG(LOG_TAG, "Register LSM HIDL service");device_->start_recognition = stdev_start_recognition;device_->stop_recognition = stdev_stop_recognition;//(6)SoundTriggerHw开启监听,调用SoundTriggerDevice::start_recognition()
hardware/interfaces/soundtrigger/2.3/default/SoundTriggerHw.cpp
Return<int32_t> SoundTriggerHw::startRecognition(int32_t modelHandle, const V2_0::ISoundTriggerHw::RecognitionConfig& config,const sp<V2_0::ISoundTriggerHwCallback>& /* callback */, int32_t /* cookie */)ret = mHwDevice->start_recognition(mHwDevice, client->getHalHandle(), halConfig,recognitionCallback_, client.get());//(7)SoundTriggerDetector 调用startRecognition()注册回调给到HAL层
frameworks/base/media/java/android/media/soundtrigger/SoundTriggerDetector.java
public boolean startRecognition(@RecognitionFlags int recognitionFlags)
try {status = mSoundTriggerSession.startRecognition(mSoundModel,mRecognitionCallback, new RecognitionConfig(captureTriggerAudio,allowMultipleTriggers, null, null, audioCapabilities),runInBatterySaver);} catch (RemoteException e) {return false;}/*** This class should be constructed by the {@link SoundTriggerManager}.* @hide*/SoundTriggerDetector(ISoundTriggerSession soundTriggerSession,@NonNull GenericSoundModel soundModel,@NonNull Callback callback, @Nullable Handler handler) {mSoundTriggerSession = soundTriggerSession;mSoundModel = soundModel;mCallback = callback;if (handler == null) {mHandler = new MyHandler();} else {mHandler = new MyHandler(handler.getLooper());}mRecognitionCallback = new RecognitionCallback();}事件上报时有两个结构体,一个是sound_trigger_recognition_config,这个是sound_trigger_recognition配置相关的;
还有一个sound_trigger_recognition_event,这个的英文注释如下:Generic recognition event sent via recognition callback。
prebuilts/vndk/v32/arm/include/system/media/audio/include/system/sound_trigger.h
/** configuration for sound trigger capture session passed to start_recognition()*/struct sound_trigger_recognition_config {audio_io_handle_t    capture_handle;    /* IO handle that will be used for capture.N/A if capture_requested is false */audio_devices_t      capture_device;    /* input device requested for detection capture */bool                 capture_requested; /* capture and buffer audio for this recognitioninstance */unsigned int         num_phrases;   /* number of key phrases recognition extras */struct sound_trigger_phrase_recognition_extra phrases[SOUND_TRIGGER_MAX_PHRASES];/* configuration for each key phrase */unsigned int        data_size;         /* size of opaque capture configuration data */unsigned int        data_offset;       /* offset of opaque data start from start of this struct(e.g sizeof struct sound_trigger_recognition_config) */};Generic recognition event sent via recognition callbackstruct __attribute__((aligned(8))) sound_trigger_recognition_event {int                              status;            /* recognition status e.g.RECOGNITION_STATUS_SUCCESS */sound_trigger_sound_model_type_t type;              /* event type, same as sound model type.e.g. SOUND_MODEL_TYPE_KEYPHRASE */sound_model_handle_t             model;             /* loaded sound model that triggered theevent */bool                             capture_available; /* it is possible to capture audio from thisutterance buffered by theimplementation */int                              capture_session;   /* audio session ID. framework use */int                              capture_delay_ms;  /* delay in ms between end of modeldetection and start of audio availablefor capture. A negative value is possible(e.g. if key phrase is also available forcapture */int                              capture_preamble_ms; /* duration in ms of audio capturedbefore the start of the trigger.0 if none. */bool                             trigger_in_data; /* the opaque data is the capture ofthe trigger sound */audio_config_t                   audio_config;        /* audio format of either the trigger inevent data or to use for capture of therest of the utterance */unsigned int                     data_size;         /* size of opaque event data */unsigned int                     data_offset;       /* offset of opaque data start from start ofthis struct (e.g sizeof structsound_trigger_phrase_recognition_event) */};

SoundTriggerDetector调用startRecognition()时将事件监听回调注册到SoundTriggerHal层。

2、高通芯片AudioReach架构芯片平台ADSP层唤醒事件上报流程

唤醒上报事件代码时序(高通AudioReach架构芯片平台)(1)唤醒模块代码上报唤醒事件
capi_wakeup_raise_event_to_dsp_client()me_ptr->cb_info.event_cb(me_ptr->cb_info.event_context,CAPI_EVENT_DATA_TO_DSP_CLIENT_V2, &event_info)CAPI_EVENT_DATA_TO_DSP_CLIENT_V2 = 15(2)capi的callback()回调接口处理此事件消息
gen_topo_capi_cb_handler.c
gen_topo_capi_callback_base(gen_topo_module_t *module_ptr,capi_event_id_t    id,capi_event_info_t *event_info_ptr)switch (id)case CAPI_EVENT_DATA_TO_DSP_CLIENT:case CAPI_EVENT_DATA_TO_DSP_CLIENT_V2:return ar_result_to_capi_err(topo_ptr->topo_to_cntr_vtable_ptr->handle_capi_event(module_ptr, id, event_info_ptr));ADSP.HT.5.8/adsp_proc/avs/fwk/spf/containers/spl_cntr/core/src/spl_cntr.c.handle_capi_event                           = spl_cntr_handle_capi_event,(3)调用spf框架的spl_cntr_handle_capi_event()
ADSP.HT.5.8/adsp_proc/avs/fwk/spf/containers/spl_cntr/core/src/spl_cntr_event_util.c
ar_result_t spl_cntr_handle_capi_event(gen_topo_module_t *module_ptr,capi_event_id_t    event_id,capi_event_info_t *event_info_ptr){spl_cntr_t *me_ptr = (spl_cntr_t *)GET_BASE_PTR(spl_cntr_t, topo, module_ptr->topo_ptr);ar_result_t result = AR_EOK;result = cu_handle_capi_event(&me_ptr->cu, &module_ptr->gu, event_id, event_info_ptr);return result;}cu_handle_capi_event()switch (event_id)case CAPI_EVENT_DATA_TO_DSP_CLIENT_V2:{result |= cu_handle_event_data_to_dsp_client_v2_topo_cb(cu_ptr, module_ptr, event_info_ptr);break;}(4)路由到spf框架的cu_handle_event_data_to_dsp_client_v2_topo_cb()接口
ADSP.HT.5.8/adsp_proc/avs/fwk/spf/containers/cmn/container_utils/core/src/cu_utils_island.c
/* Topo callback to handle module event to DSP client v2 */ar_result_t cu_handle_event_data_to_dsp_client_v2_topo_cb(cu_base_t *        cu_ptr,gu_module_t *      module_ptr,capi_event_info_t *event_info_ptr)capi_event_data_to_dsp_client_v2_t *payload_ptr =(capi_event_data_to_dsp_client_v2_t *)(event_info_ptr->payload.data_ptr);gpr_cmd_alloc_ext_v2_t args;args.heap_index    = dest_address.a.gpr_heap_index;args.src_domain_id = dest_address.a.dest_domain_id;args.dst_domain_id = dest_address.a.src_domain_id;args.src_port      = module_ptr->module_instance_id;args.dst_port      = dest_address.a.src_port;args.token         = payload_ptr->token;args.opcode        = APM_EVENT_MODULE_TO_CLIENT;args.payload_size  = sizeof(apm_module_event_t) + payload_ptr->payload.actual_data_len;args.client_data   = 0;args.ret_packet    = &event_packet_ptr;result             = __gpr_cmd_alloc_ext_v2(&args);//调用gpr接口发送gpr消息给到client端result = __gpr_cmd_async_send(event_packet_ptr);(5)调用gpr接口,为gpr消息申请分配对应的内存大小,
分配原则:先从静态内存池分配,静态分配失败,再从动态内存分配,两者都失败,上报内存分配失败。
ADSP.HT.5.8/adsp_proc/gpr/core/src/gpr_drv_island.c
uint32_t __gpr_cmd_alloc_ext_v2(gpr_cmd_alloc_ext_v2_t *args)rc = __gpr_cmd_alloc_v2(args->payload_size, args->heap_index, &new_packet);uint32_t __gpr_cmd_alloc_v2(uint32_t alloc_size, gpr_heap_index_t heap_index, gpr_packet_t **ret_packet)new_packet = (gpr_packet_t *)gpr_memq_alloc(block);// If packet couldnt not be allocated in static pool, check dynamic poolgpr_allocate_dynamic_packet(&new_packet, packet_size);

http://www.lryc.cn/news/583533.html

相关文章:

  • 常见 HTTP 方法的成功状态码200,204,202,201
  • C++并发编程-11. C++ 原子操作和内存模型
  • Token 和 Embedding的关系
  • 通过Tcl脚本命令:set_param labtools.auto_update_hardware 0
  • AI Agent:我的第一个Agent项目
  • 在 macOS 上安装与自定义 Oh My Zsh:让终端美观又高效 [特殊字符]
  • css支持if else
  • WIndows 编程辅助技能:格式工厂的使用
  • 单片机STM32F103:DMA的原理以及应用
  • React面试高频考点解析
  • 【LeetCode 热题 100】21. 合并两个有序链表——(解法二)递归法
  • Spark流水线数据对比组件
  • 第6章应用题
  • 01-elasticsearch-搭个简单的window服务-ik分词器-简单使用
  • 【01】MFC入门到精通—— MFC新建基于对话框的项目 介绍(工作界面、资源视图 、类视图)
  • 【前端】ikun-markdown: 纯js实现markdown到富文本html的转换库
  • Java SE 实现简单的图书管理系统(完善菜单操作)
  • 【DOCKER】-3 数据持久化
  • 项目进度受制于资源分配,如何动态调配资源
  • 20250709: WSL+Pycharm 搭建 Python 开发环境
  • PHP 基于模板动态生成 Word 文档:图片 + 表格数据填充全方案(PHPOffice 实战)
  • 爬虫-数据解析
  • 20-C#构造函数--虚方法
  • 机器视觉之工业相机讲解
  • 【leetcode100】下一个排列
  • 题解:P13017 [GESP202506 七级] 线图
  • RAC-CELL(小区)处理
  • 射频前端的革新力量:ATR2057超低噪声放大器深度解析
  • C#基础篇(10)集合类之列表
  • AMIS全栈低代码开发