audio:mt6236 录音驱动小结

来源:互联网 发布:淘宝上的紫砂壶能买吗 编辑:程序博客网 时间:2024/05/16 06:42

目录

一 基本框架

二 源码分析

三 FAQ

 

摘要

本文主要描述MT6236平台之录音流程,且着重针对驱动源代码做分析,包括时序图,源码层次,以及做了问题的总结。


一基本框架

1.1框架

 















二源码分析

2.1时序图 与状态机

以36为例:

时序图:不单单以任务为节点,

 

















2.2主要文件,函数以及数据结构

这里只要讨论驱动相关:

相关宏:__MED_AUD_REC_MOD__

      AUD_REC_ENABLE

      DSP_SOLUTION

      SMART_PHONE_CORE

根据audio.mak: 36的 med and audio的代码都是使用V1

 

文件(自上往下)

描述

UI

 

vapp_soundrec_util.cpp

vapp_soundrec.cpp

录音应用UI相关

mdi_audio.c

mdi层封装record接口函数,当然还包括其他函数

aud_api.c

API包括了主要的音频模块接口函数,播放器,录音等等,到这里未知,这些文件都是为UI层服务的接口文件。

aud_ilm.c

audio消息封装层,转发消息到: MED_TASK

Med_Task

 

aud_media.c

Med_task的对UI层的消息的执行函数

aud_record.c

独立的录音的功能函数--这里是med_task来调用的。

aud_recorder_media.c

media层函数定义,功能:操作内存,与L1audio Task 交互。操作硬件层,调用PCM WAV等算法。

 

 

 

函数(自上而下)

描述

UI

 

vadp_soundrec_rec_start()

录音应用的UI接口

mdi_audio_start_record()

mdi层封装接口

media_aud_start_record()

API层音频模块接口,到这里未知,这些文件都是为UI层服务的接口函数。

aud_send_record_req()

Audio ILM层负责封装消息给Med Task

Med TASK

 

aud_media_record_req_hdlr()

MedTask层对UI层的消息处理函数

aud_rec_start_record()

独立的录音的功能函数--这里是med_task来调用的。

_aud_recorder_media_record()

media层函数定义,功能…..录音的硬件驱动都在这里操作。

Media_Record()

最终操作DSP HW的函数,注册回调函数给L1audio_Task

 

根据每一层的contex数据结构来理解:

数据结构(自上而下)

组成

描述

g_sndrec_cntx

 

UI层的audio record上下文

aud_context_p

 

Med task层的audio record 上下文

med_aud_recorder_t

 kal_int32 (*open)

 kal_int32 (*close)

 kal_int32 (*start)

 kal_int32 (*stop)

…...

Audio Recorder interfaces这些都是media层的接口,

直接打开底层硬件驱动,包括文件操作,设置格式,申请释放buffer,

调用wav PCM等算法

 

 

 

 

请注意关键点:

1. #defineAUD_RECORDER_MEM_MARGIN             (512)//对齐

    #defineAUD_RECORDER_BUFFER_THRESHOLD       (200)  /* 200 words (400 bytes) bydefault */

2. 刚开始录的时候要跳过2fame

  Media_Record函数里面: media.recorded_time = -40; // skip two speechframes

 

3.开关MIC:L1SP_SetInputSource(custom_cfg_hw_aud_input_path(msg_p->input_source));

4.文件创建:_aud_recorder_media_open()

5.Allocate buffers_aud_recorder_media_record()

5.1Buffer for amr:

5.2buffer for ring:---采用环形缓冲机制,-----详细内容请是参考环形buffer设计原理

 aud_util_alloc_ring_buffer_ext(AUD_RING_BUFFER_SIZE,&self_p->ring_buffer_p);

 Media_SetBuffer(self_p->ring_buffer_p,AUD_RING_BUFFER_LEN);

--->size:AUD_RING_BUFFER_SIZE----是BUFFER_THRESHOLD的10倍

--->len:AUD_RING_BUFFER_LEN

和Media层的media.ctrl.rb_size ;media.ctrl.rb_base一致,

 

Med_v Task 读取L1audio_Buffer的新data:Media_GetReadBuffer();

 

6.L1audio与Med Task之间的回调函数

首先注册回电函数: _aud_recorder_media_event_callback_fct

 Med Task:

          Media_Record(media_format, _aud_recorder_media_event_callback_fct,param_p);

------>media.media_handler = media_handler;

L1audio_Task:

    mediaInit(L1Audio_GetAudioID() );

----->L1Audio_SetEventHandler( uint16 audio_id,L1Audio_EventHandler handler )

----->l1audio.evHandler[audio_id] = handler;//handle放到L1audio的handle里面

 

回调函数_aud_recorder_media_read_data_fct()---->write data to FS

更新文件大小偏移,这样文件就可以逐步加大

            /* Update file offset */

            self_p->file_offset += len;

            *written_len = len;

 

Callback 门限是:AUD_RECORDER_BUFFER_THRESHOLD;

 

7.通过L1audio_Task来读取DSP的数据

函数:amrDediEncReadFromDSP-------AMR

  pcmReadFromDSP();-------PCM

 wavReadFromDSP((int16*)wav.tmp_buf[wav.tmp_w&FRAME_BUF_MASK] );----WAV

…...等等

8.驱动硬件开始录音的函数:

amrRecord()

/*

    * Stuff no-dataframe first to handle the situation when DSP issues

    * interrupt toMCU for recording, but at that timethe AMR codec in DSP

    * has notfinished its job.

    */

 

 

三FAQ总结

1.DSP层上面时候发出中断呢?

首先:DSP的时钟与NCU同步,估计是通过系统网络同步时钟:TDMA定时器,定时地产生中断。

其次 :当buffer到达AUD_RECORDER_BUFFER_THRESHOLD时候,触发中断通知MCU。

处理流程是这样

isrC_Main---->定时地发送中断信号过来,---->激活高级中断处理例程kal_activate_hisr(l1audio.hisr);--->HISR判断是否满足AUD_RECORDER_BUFFER_THRESHOLD----->满足则通知L1audio_Task 和Med_Task--->写数据到FS.

 

2.文件时如何逐步加大的呢?也就是说offset写的过程。

一开始就会创建一个临时文件,每次buffer读回来写到文件之后,offset就计算一下偏移大小,

/* Update file offset */

self_p->file_offset += len;

 *written_len =len;

原先的文件句柄不变,根据这个offset,不停地带该文件句柄的最后一簇,查找长度为len的簇,累计到该句柄后面。

更详细请参考文件系统读写流程。

 

3.能否同时录音上行和下行呢?

No; 

函数amrRecord(){ *DP_SC_MUTE = 0x0002;  /* uplink path only */}

 

4.录音格式是那一种?

Arm---:MEDIA_AMR_WB

Wav:---: