rtx操作系统在bes上的应用之音频处理

说明

这只是讲把算法集成到bes2300 sdk的位置与流程分析。


流程

在系统启动后,调用main(),main()函数会调用到af_open()与app_audio_open(),之后它会创建一个任务,主要代码如下(audioflinger.c):

<code>    af_thread_tid = osThreadCreate(osThread(af_thread), NULL);
    af_default_priority = af_get_priority();
    osSignalSet(af_thread_tid, 0x0);/<code>

将上面的宏定义展开即:

<code>#define osThread(af_thread)  \\
&os_thread_def_af_thread/<code>

然而,整个sdk中有如下定义:

<code>osThreadDef(af_thread, osPriorityAboveNormal, AF_STACK_SIZE);

#define osThreadDef(name, priority, stacksz) \\
uint32_t os_thread_def_stack_##name [stacksz / sizeof(uint32_t)]; \\
osThreadDef_t os_thread_def_##name = \\
{ (name), (priority), (stacksz), (os_thread_def_stack_##name)}/<code>

展开即,

<code>#define osThreadDef(af_thread, 1, stacksz)  \\
uint32_t os_thread_def_stack_af_thread [stacksz / sizeof(uint32_t)]; \\
osThreadDef_t os_thread_def_af_thread = \\
{ (af_thread), (1), (stacksz), (os_thread_def_stack_af_thread)}/<code>

其中,

<code>typedef enum  {
osPriorityIdle = -3, ///< priority: idle (lowest)
osPriorityLow = -2, ///< priority: low
osPriorityBelowNormal = -1, ///< priority: below normal
osPriorityNormal = 0, ///< priority: normal (default)
osPriorityAboveNormal = +1, ///< priority: above normal
osPriorityHigh = +2, ///< priority: high
osPriorityRealtime = +3, ///< priority: realtime (highest)
osPriorityError = 0x84 ///< system cannot determine priority or thread has illegal priority

} osPriority;/<code>

任务结构体定义为:

<code>typedef struct os_thread_def  {
os_pthread pthread; ///< start address of thread function
osPriority tpriority; ///< initial thread priority
uint32_t stacksize; ///< stack size requirements in bytes
uint32_t *stack_pointer; ///< pointer to the stack memory block
struct OS_TCB tcb;
#if __RTX_CPU_STATISTICS__
const char * name_str;
#endif
} osThreadDef_t;/<code>

所以,该任务执行的内容:

<code>static void af_thread(void const *argument)
{
osEvent evt;
uint32_t signals = 0;
enum AUD_STREAM_ID_T id;
enum AUD_STREAM_T stream;

while(1)
{
#ifdef __USE_DMA_IRQ_QUEUE__
evt = osMessageGet(af_thread_dma_irq_queue_id, osWaitForever);
signals = (uint32_t)evt.value.p;
if (evt.status == osEventMessage)
#else
//wait any signal
evt = osSignalWait(0x0, osWaitForever);
signals = evt.value.signals;
//TRACE("[%s] status = %x, signals = %d", __func__, evt.status, evt.value.signals);

if(evt.status == osEventSignal)
#endif
{
for(uint8_t i=0; i {
if(signals & (1 << i))
{
id = (enum AUD_STREAM_ID_T)(i >> 1);
stream = (enum AUD_STREAM_T)(i & 1);

af_thread_stream_handler(id, stream);

#ifdef AF_STREAM_ID_0_PLAYBACK_FADEOUT
af_stream_stop_process(role, role->dma_buf_ptr + PP_PINGPANG(role->ctl.pp_index) * (role->dma_buf_size / 2), role->dma_buf_size / 2);
#endif
}
}
}
else
{
TRACE("[%s] ERROR: evt.status = %d", __func__, evt.status);
continue;
}
}
}
/<code>

注意,函数中调用了:

<code>af_thread_stream_handler(id, stream);/<code>

而该函数调用到了如下内容:

<code>role->handler(buf, role->dma_buf_size / 2);/<code>

再返回到前面,看函数app_audio_open();这个函数会调用到函数:

<code>app_set_threadhandle(APP_MODUAL_AUDIO, app_audio_handle_process);/<code>

而函数:

<code>static int app_audio_handle_process(APP_MESSAGE_BODY *msg_body)/<code>

会调用到:

<code>int app_bt_stream_open(APP_AUDIO_STATUS* status)/<code>

之后,会调用到:

<code>nRet = bt_sbc_player(PLAYER_OPER_START, freq,status->param);/<code>

可以看到,里面有这么一句代码:

<code>stream_cfg.handler = bt_sbc_player_more_data;/<code>

和这个函数:

<code>af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg);/<code>

焦点再聚焦到函数:

<code>bt_sbc_player_more_data/<code>

可以看到该函数最后会调用函数

<code>audio_eq_run(buf, len);/<code>

所以,这里基本就是实际的可以添加音频处理的函数了。

再看函数

<code>af_stream_open():/<code>

调用了这样一句代码:role->cfg = *cfg;其中,cfg就是上面的:stream_cfg。

另外还有:role->handler = cfg->handler;

所以,这样就能在af_thread()中调用到音频处理函数了。


分享到:


相關文章: