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

tlv32aic32 外部DAC的I2S音频流运行过程分析

              tlv32aic32 外部DAC的I2S音频流运行过程分析

#include "codec_tlv32aic32.h"

AF_TRACE_DEBUG();

    struct af_stream_cfg_t *role;

    enum AF_RESULT_T ret;

    enum AUD_STREAM_USE_DEVICE_T device;

    struct HAL_DMA_CH_CFG_T *dma_cfg = NULL;

    role = af_get_stream_role(id, stream);

    TRACE(3,"[%s] id = %d, stream = %d", __func__, id, stream);

    ASSERT(cfg->data_ptr != NULL, "[%s] ERROR: data_ptr == NULL!!!", __func__);

    ASSERT(((uint32_t)cfg->data_ptr) % 4 == 0, "[%s] ERROR: data_ptr(%p) is not align!!!", __func__, cfg->data_ptr);

    ASSERT(cfg->data_size != 0, "[%s] ERROR: data_size == 0!!!", __func__);

ret = AF_RES_FAILD;

    af_lock_thread();

    //check af is open

    if (role->ctl.status != AF_STATUS_OPEN_CLOSE) {

        TRACE(2,"[%s] ERROR: status = %d",__func__, role->ctl.status);

        goto _exit;

    }

    role->cfg = *cfg;

    device = cfg->device;

    role->ctl.use_device = device;

    dma_cfg = &role->dma_cfg;

    memset(dma_cfg, 0, sizeof(*dma_cfg));

    dma_cfg->handler = af_dma_irq_handler;

    if (stream == AUD_STREAM_PLAYBACK) {

        AF_TRACE_DEBUG();

        dma_cfg->src_periph = (enum HAL_DMA_PERIPH_T)0;

        dma_cfg->type = HAL_DMA_FLOW_M2P_DMA;

#ifdef AF_DEVICE_EXT_CODEC

        } else if (device == AUD_STREAM_USE_EXT_CODEC) {

            AF_TRACE_DEBUG();

                     //trace(0,"tlv32aic32_open()\n"); 

            tlv32aic32_open();

            tlv32aic32_stream_open(stream);----------à hal_i2s_open

            dma_cfg->dst_periph = HAL_AUDMA_I2S0_TX;

#endif

    af_stream_update_dma_buffer(id, stream, role, cfg);

    role->handler = cfg->handler;

    af_set_status(id, stream, AF_STATUS_STREAM_OPEN_CLOSE);

#ifndef RTOS

    af_clear_flag(&af_flag_signal, 1 << (id * 2 + stream));

    af_set_flag(&af_flag_open, 1 << (id * 2 + stream));

#endif

#ifdef DMA_RPC_CLI

    if (dma_rpcif_enabled(id, stream)) {

        dma_rpc_stream_open(id, stream, (void *)&role->cfg);

    }

#endif

    AF_TRACE_DEBUG();

    ret = af_stream_setup_internal(id, stream, &role->cfg, false);

_exit:

af_unlock_thread();

af_stream_sw_gain_open(id, stream, cfg->sample_rate, cfg->bits, cfg->channel_num,

                                    AUDIO_OUTPUT_SW_GAIN_MODE_IIR);

#ifdef DMA_RPC_CLI

        if (dma_rpcif_enabled(id, stream)) {

            dma_cfg->ch = dma_rpc_get_chan(dma_cfg->dst_periph, HAL_DMA_HIGH_PRIO);

            role->dma_base = dma_rpc_get_base_addr(dma_cfg->ch);

        } else

#endif

        {

            dma_cfg->ch = hal_audma_get_chan(dma_cfg->dst_periph, HAL_DMA_HIGH_PRIO);

            role->dma_base = hal_audma_get_base_addr(dma_cfg->ch);

        }

AF_TRACE_DEBUG();

        dma_cfg->dst_periph = (enum HAL_DMA_PERIPH_T)0;

        dma_cfg->type = HAL_DMA_FLOW_P2M_DMA;

#ifdef AF_DEVICE_EXT_CODEC

        } else if (device == AUD_STREAM_USE_EXT_CODEC) {

            AF_TRACE_DEBUG();

            tlv32aic32_open();

            tlv32aic32_stream_open(stream);

            dma_cfg->src_periph = HAL_AUDMA_I2S0_RX;

#endif

#ifdef AF_DEVICE_EXT_CODEC

    } else if (device == AUD_STREAM_USE_EXT_CODEC) {

        AF_TRACE_DEBUG();

        struct tlv32aic32_config_t tlv32aic32_cfg;

        memset(&tlv32aic32_cfg, 0, sizeof(tlv32aic32_cfg));

        tlv32aic32_cfg.bits = cfg->bits;

        tlv32aic32_cfg.channel_num = cfg->channel_num;

        tlv32aic32_cfg.channel_map = cfg->channel_map;

        tlv32aic32_cfg.sample_rate = cfg->sample_rate;

        tlv32aic32_cfg.use_dma = AF_TRUE;

        tlv32aic32_cfg.chan_sep_buf = cfg->chan_sep_buf;

        tlv32aic32_cfg.sync_start = cfg->sync_start;

        tlv32aic32_cfg.slot_cycles = cfg->slot_cycles;

        tlv32aic32_stream_setup(stream, &tlv32aic32_cfg);------à hal_i2s_setup_stream

#endif

memset(&i2s_cfg, 0, sizeof(i2s_cfg));

        i2s_cfg.use_dma = AF_TRUE;

        i2s_cfg.chan_sep_buf = cfg->chan_sep_buf;

        i2s_cfg.sync_start = cfg->sync_start;

        i2s_cfg.cycles = cfg->slot_cycles;

        i2s_cfg.bits = cfg->bits;

        i2s_cfg.channel_num = cfg->channel_num;

        i2s_cfg.channel_map = cfg->channel_map;

        i2s_cfg.sample_rate = cfg->sample_rate;

        i2s_cfg.ext_mclk_freq = cfg->ext_mclk_freq;

        hal_i2s_setup_stream(i2s_id, stream, &i2s_cfg);

#ifdef AF_DEVICE_EXT_CODEC

    } else if (device == AUD_STREAM_USE_EXT_CODEC) {

        AF_TRACE_DEBUG();

        tlv32aic32_stream_start(stream);----------à hal_i2s_start_stream

#endif

#ifdef AF_DEVICE_EXT_CODEC

    } else if (device == AUD_STREAM_USE_EXT_CODEC) {

        AF_TRACE_DEBUG();

        tlv32aic32_stream_stop(stream);

#endif

#ifdef AF_DEVICE_EXT_CODEC

    } else if (device == AUD_STREAM_USE_EXT_CODEC) {

        AF_TRACE_DEBUG();

        tlv32aic32_stream_close(stream);

#endif

af_unlock_thread();

分析结论:

增加了lock锁机制,open ,   setup, 以及start 都有一对锁,调用的i2s底层是一样的,

   以及DMA 中断相关配置 ,更新DMA buf的配置。   

音频引擎框架增加了一些机制!

http://www.dtcms.com/a/525124.html

相关文章:

  • I/V自动曲线量测仪的主要功能、测量方法和应用
  • 什么是电子负载?爱科赛博电子负载应用探讨
  • 2025.10.24总结
  • 邯郸哪里做网站优化thinkphp企业网站源码
  • BUYCOIN:以社区共治重构加密交易版图,定义交易所3.0时代
  • 建立平台网站需要花多少钱国贸附近网站建设
  • 【Linux C/C++开发】epoll模式的开源库及原生socket实现
  • ARP 报文和 IP 数据报的 区分与联系
  • html网站开发目标临沂做网站多少钱
  • 代谢组学之新手入门级知识概览
  • 开关电源拓扑工程宝典:从原理到实战的深度设计指南
  • 深度学习SE,CBAM,ECA,SimAM模块汇总之SE
  • 10. Python 列表:从单元素更新到切片批量处理
  • 气凝胶基复合相变材料研究进展
  • 天门市网站建设seowordpress小说插件
  • 哪个网站的织梦源码好品牌的网站建设
  • 卷积核权重优化
  • iftop排查带宽问题
  • uniapp开发微信小程序使用物流服务的查询组件展示订单物流信息,以及使用中会遇到的问题
  • 天河做网站营销推广公司经营范围
  • wordpress 评论表情插件金沙百度seo优化公司
  • Ubuntu (Linux) 安装Docker
  • 鸿蒙OS 生命周期中调用的函数流程图
  • 宁国建设投资有限公司网站网站开发模合同
  • vue3 confirm倒计时
  • 定制网站与模板建站维护二级网站建设基本情况
  • 流行网站开发工具wordpress主题屋
  • ManiSkill2学习笔记
  • LeetCode:200. 岛屿数量
  • 【C】函数指针