トイテック本社 2026-03-16 08:52 采纳率: 0%
浏览 8

AC696X BR25系列(Jieli)一种完全独立的双音频输出方法

问题遇到的现象和发生背景

我在使用BR25系列(Jieli)SDK做音频输出时,希望通过DACL和DACR实现完全独立的两路音频输出(不同采样率、不同时间轴/不同起始时刻)。当前工程中DAC输出模式为 DAC_OUTPUT_LR,DACL/DACR是同一DAC的左右声道。我想仅通过软件(不改硬件、不加外部IIS/DAC)实现两路完全独立播放。

操作环境、软件版本等信息

芯片:BR25系列
工程:soundbox
关键配置:TCFG_AUDIO_DAC_CONNECT_MODE = DAC_OUTPUT_LR
相关文件:include_lib/media/media_develop/media/cpu/br25/asm/dac.h

尝试过的解决方法

查阅 dac.h 中的输出模式(如 DAC_OUTPUT_FRONT_LR_REAR_LR 四声道单端输出)。
搜索工程中 AUDIO_DAC_MULTI_CHANNEL_ENABLE、DAC_OUTPUT_FRONT_LR_REAR_LR 的使用位置。
理解为多声道只是“更多通道”但仍共享时钟/采样率,因此看起来并不能做到完全独立。

我想要达到的结果

在不改硬件的前提下,仅通过程序实现两路完全独立音频输出:
・不同采样率
・不同开始/停止时序
・互不影响

  • 写回答

2条回答 默认 最新

  • 檀越@新空间 2026-03-16 08:55
    关注

    上午好☀️☀️☀️️
    本答案参考通义千问

    你提出的问题非常具有挑战性,尤其是在 BR25系列(Jieli) 芯片上实现 两路完全独立的音频输出(DACL 和 DACR),且不修改硬件、不使用外部 IIS/DAC 的前提下。目前芯片的默认配置是 DAC_OUTPUT_LR,即左右声道共享同一个 DAC 模块和时钟,这限制了你对两路音频进行完全独立控制的可能性。


    ✅ 问题分析

    1. 当前配置限制

    • 当前配置为 DAC_OUTPUT_LR,表示左右声道共用一个 DAC 模块。
    • 即使你尝试使用其他模式如 DAC_OUTPUT_FRONT_LR_REAR_LR,这些模式仍然共享时钟和采样率,无法实现真正的独立输出。

    2. 你的需求

    • DACL 和 DACR 必须完全独立:包括:
      • 不同采样率
      • 不同时序(起始/停止时间)
      • 互不影响

    🚫 硬件限制

    在 BR25 系列中,DACL 和 DACR 是同一个 DAC 模块的左右通道,它们共享相同的时钟源(通常是 MCLK 或 BCLK),这意味着:

    • 无法独立设置采样率(因为时钟源是统一的)
    • 无法独立启动/停止(因为共享时钟和 FIFO 缓冲区)

    因此,从硬件角度来看,无法通过软件直接实现两路完全独立的音频输出


    ✅ 可能的解决方案(仅限软件层面)

    虽然硬件上存在限制,但你可以通过一些技巧尽量模拟“独立”的效果,以下是一些可行方案:


    🔧 方案一:多线程 + 音频缓冲区 + 自定义时钟管理

    目标:

    • 通过两个线程分别处理 ACL 和 ACR 的音频数据
    • 使用不同的缓冲区和播放时机
    • 模拟“独立”播放

    实现步骤:

    1. 创建两个独立的音频播放线程

      • 一个用于处理 DACL 数据(左声道)
      • 一个用于处理 DACR 数据(右声道)
    2. 为每个线程分配独立的音频缓冲区

      • 使用 audio_buffer_t 结构体或自定义缓冲区
      • 设置不同的采样率和播放节奏
    3. 手动控制播放时机

      • 在每个线程中维护一个时间戳或帧计数器
      • 根据时间戳控制播放开始和结束
    4. 使用 audio_play() 函数异步播放

      • 启动两个播放任务,分别传入各自的缓冲区

    示例代码片段(伪代码):

    // 线程1:处理 DACL(左声道)
    void dac_left_thread(void *arg) {
        audio_buffer_t *buf_left = create_audio_buffer(44100, 16, 2); // 44.1kHz
        while (1) {
            if (buffer_has_data(buf_left)) {
                audio_play(buf_left);
            }
            os_time_dly(10); // 控制播放节奏
        }
    }
    
    // 线程2:处理 DACR(右声道)
    void dac_right_thread(void *arg) {
        audio_buffer_t *buf_right = create_audio_buffer(48000, 16, 2); // 48kHz
        while (1) {
            if (buffer_has_data(buf_right)) {
                audio_play(buf_right);
            }
            os_time_dly(10); // 控制播放节奏
        }
    }
    

    ⚠️ 注意:由于 DACL 和 DACR 共享同一个 DAC 模块,实际输出可能会有串扰或失真,需测试验证。


    🔧 方案二:使用 DAC 输出模式 DAC_OUTPUT_FRONT_LR_REAR_LR(四声道)

    说明:

    • 该模式支持四声道输出(Front Left, Front Right, Rear Left, Rear Right)
    • 尽管仍共享时钟,但可以分别发送不同内容到左右声道

    优点:

    • 可以分别控制左右声道的数据流
    • 一定程度上实现“独立”播放

    代码示例(启用四声道模式):

    // 在初始化时设置输出模式
    TCFG_AUDIO_DAC_CONNECT_MODE = DAC_OUTPUT_FRONT_LR_REAR_LR;
    
    // 分别向左右声道写入不同数据
    audio_write(DAC_LEFT_CHANNEL, left_data, len);
    audio_write(DAC_RIGHT_CHANNEL, right_data, len);
    

    ⚠️ 该方式不能真正实现“独立”的采样率和时序,但可以实现“逻辑上的独立”。


    🔧 方案三:使用外部 DAC 模块(非推荐)

    虽然你提到“不加外部 IIS/DAC”,但如果这是唯一可行方案,可以考虑:

    • 使用 I2S 接口连接外部 DAC 模块
    • 通过 I2S 接口分别驱动左右声道
    • 这样可以真正实现独立的音频输出

    ⚠️ 但此方法需要硬件改动,不符合你的要求。


    ✅ 最终建议

    | 方案 | 是否可实现独立 | 是否需要改硬件 | 是否推荐 | |------|----------------|----------------|----------| | 多线程 + 自定义时钟 | ❌ 无法真正独立 | ✅ 不需要 | ⚠️ 有一定风险,需测试 | | 四声道模式 | ❌ 无法独立采样率 | ✅ 不需要 | ✅ 推荐(有限独立) | | 外部 DAC | ✅ 完全独立 | ❌ 需要硬件 | ✅ 推荐(如允许) |


    📌 总结

    BR25 系列(Jieli) 中,DACL 和 DACR 是同一 DAC 模块的左右通道,因此无法通过软件实现完全独立的音频输出(不同采样率、不同时间轴)。如果你必须使用现有硬件,建议采用多线程 + 自定义缓冲区 + 时间戳控制的方式,尽管存在一定的局限性。

    如果可以接受硬件改动,使用外部 IIS/DAC 模块是最理想的解决方案,可以真正实现两路独立音频输出。


    如需进一步优化代码或提供具体实现,请提供更多关于你使用的 SDK 版本和相关 API 的信息。

    评论

报告相同问题?

问题事件

  • 创建了问题 3月16日