This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TLV320AIC3104:如何同时将两个不同的音频文件播放到两个不同的扬声器?

Guru**** 1127450 points
Other Parts Discussed in Thread: TLV320AIC3104
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/audio-group/audio/f/audio-forum/1087233/tlv320aic3104-how-to-play-two-different-audio-files-to-two-different-speakers-at-the-same-time

部件号:TLV320AIC3104

我有一个定制的主板,它有一个处理器,编解码器,音频放大器和扬声器连接到左右声道。 我的目标是能够同时向两个不同的扬声器播放两个不同的音频文件。 目前,两个扬声器正在播放相同的音频。

我正在使用以下IC:

  1. 处理器:AM3358BZCZ100
  2. 编解码器:TLV320AIC3104
  3. 操作系统:Debian GNU/Linux 9 (Stretch)
  4. 音频放大器:BD5634NUX

注:我只提到了相关IC。

我不知道这是可以通过用户空间中的i2c寄存器设置来解决的路由问题,还是我必须在内核空间中修复的问题。  

任何帮助/指导都将受到欢迎。

谢谢你。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,

    此AIC3104编解码器只有1个DAI,您打算如何同时运行2个音频文件?

    此致。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    一次只能从一个扬声器播放音频吗? 我的意思是先只从左声道播放音频,然后再从右声道播放音频。  

    谢谢你。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    编解码器左右DAC或输出模块(如HP)具有自己的电源控制,因此您可以根据需要进行配置。

    我有兴趣了解您如何将系统配置为只能左播放,然后只能右播放。 我能看到你的DTS吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的及时回复。 我正在通过左侧_LOP/左 侧LOM处的音频放大器和AIC3104右侧_LOP/右侧LOM引脚处的另一个扬声器(Spk2)连接一个8欧姆扬声器(Spk1)。 下面是我要实现的目标:在设置1中:当我在Linux终端中使用命令(如“aplay audiofile.wav”)播放音频时,我希望声音仅来自Spk1。 在设置2中:重复相同的操作时,我希望声音仅来自Spk2。  那么,您认为这两种设置是什么? 我如何及在何处作出这些调整,以达致上述目标? 下面是我的DTS文件:

    /*
     * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
     *
     * This program is free software; you can redistribute it and/or modify
     * it under the terms of the GNU General Public License version 2 as
     * published by the Free Software Foundation.
     */
    
    /dts-v1/;
    /plugin/;
    
    #include <dt-bindings/gpio/gpio.h>
    #include <dt-bindings/pinctrl/am33xx.h>
    
    / {
            compatible = "ti,beaglebone", "ti,beaglebone-black", "ti,beaglebone-green";
    
            /* identification */
            part-number = "BB-BONE-AUDI-02";
            version = "00A0", "A0";
    
            /* state the resources this cape uses */
            exclusive-use =
                    /* the pin header uses */
                    "P9.31",        /* mcasp0: mcasp0_aclkx */
                    "P9.29",        /* mcasp0: mcasp0_fsx */
                    "P9.28",        /* mcasp0: mcasp0_axr2 */
                    "P9.25",        /* mcasp0: mcasp0_ahclkx */
                    "P9.30",        /* mcasp0: mcasp0_axr0 */
                    /* the hardware ip uses */
                    "gpio3_21",
                    "mcasp0";
    
            /*
             * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
             */
            fragment@0 {
                    target-path="/";
                    __overlay__ {
    
                            chosen {
                                    overlays {
                                            BB-BONE-AUDI-02-00A0 = __TIMESTAMP__;
                                    };
                            };
                    };
            };
    
            /*
             * Free up the pins used by the cape from the pinmux helpers.
             */
            fragment@1 {
                    target = <&ocp>;
                    __overlay__ {
                            P9_25_pinmux { status = "disabled"; };  /* mcasp0_ahclkx */
                            P9_28_pinmux { status = "disabled"; };  /* mcasp0_axr2 */
                            P9_29_pinmux { status = "disabled"; };  /* mcasp0_fsx */
                            P9_30_pinmux { status = "disabled"; };  /* mcasp0_axr0 */
                            P9_31_pinmux { status = "disabled"; };  /* mcasp0_aclkx */
                    };
            };
    
            fragment@2 {
                    target = <&am33xx_pinmux>;
                    __overlay__ {
                            bone_audio_cape_audio_pins: pinmux_bone_audio_cape_audio_pins {
                                    pinctrl-single,pins = <
                                            AM33XX_IOPAD(0x990, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* mcasp0_aclkx.mcasp0_aclkx */
                                            AM33XX_IOPAD(0x994, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* mcasp0_fsx.mcasp0_fsx, INPUT */
                                            AM33XX_IOPAD(0x998, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* mcasp0_axr0.mcasp0_axr0 */
                                            AM33XX_IOPAD(0x99c, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mcasp0_ahclkr.mcasp0_axr2 */
                                            AM33XX_IOPAD(0x9ac, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* MCASP0_AHCLKX -> MCASP0_AHCLKX (I2S_MCLK_OUT)- in */
                                            AM33XX_IOPAD(0x86c, PIN_OUTPUT_PULLDOWN | MUX_MODE7)    /* gpmc_a11.GPIO1_27 */
                                    >;
                            };
                    };
            };
    
            fragment@3 {
                    target-path="/";
                    __overlay__ {
                            clk_mcasp0_fixed: clk_mcasp0_fixed {
                                    #clock-cells = <0>;
                                    compatible = "fixed-clock";
                                    clock-frequency = <24576000>;
                            };
    
                            clk_mcasp0: clk_mcasp0 {
                                    #clock-cells = <0>;
                                    compatible = "gpio-gate-clock";
                                    clocks = <&clk_mcasp0_fixed>;
                                    enable-gpios = <&gpio1 27 0>; /* BeagleBone Black Clk enable on GPIO1_27 */
                            };
    
                            sound {
                                    compatible = "simple-audio-card";
                                    simple-audio-card,name = "AudioCape Rev B";
                                    simple-audio-card,widgets =
                                            "Headphone", "Headphone Jack",
                                            "Line", "Line In";
                                    simple-audio-card,routing =
                                            "Headphone Jack",       "HPLOUT",
                                            "Headphone Jack",       "HPROUT",
                                            "LINE1L",               "Line In",
                                            "LINE1R",               "Line In";
                                    simple-audio-card,format = "dsp_b";
                                    simple-audio-card,bitclock-master = <&sound_master>;
                                    simple-audio-card,frame-master = <&sound_master>;
                                    simple-audio-card,bitclock-inversion;
    
                                    simple-audio-card,cpu {
                                            sound-dai = <&mcasp0>;
                                    };
    
                                    sound_master: simple-audio-card,codec {
                                            #sound-dai-cells = <0>;
                                            sound-dai = <&tlv320aic3104>;
                                            clocks = <&clk_mcasp0>;
                                            clock-names = "mclk";
                                    };
                            };
                    };
            };
    
            fragment@4 {
                    target = <&i2c2>;
                    __overlay__ {
                            #address-cells = <1>;
                            #size-cells = <0>;
                            clock-frequency = <100000>;
                            status = "okay";
    
                            tlv320aic3104: tlv320aic3104@18 {
                                    #sound-dai-cells = <0>;
                                    compatible = "ti,tlv320aic3104";
                                    reg = <0x18>;
                            };
                    };
            };
    
            fragment@5 {
                    target = <&mcasp0>;
                    __overlay__ {
                            #sound-dai-cells = <0>;
                            pinctrl-names = "default";
                            pinctrl-0 = <&bone_audio_cape_audio_pins>;
                            status = "okay";
                            op-mode = <0>;  /* MCASP_IIS_MODE */
                            tdm-slots = <2>;
                            num-serializer = <16>;
                            serial-dir = <  /* 0: INACTIVE, 1: TX, 2: RX */
                                            2 0 1 0
                                            0 0 0 0
                                            0 0 0 0
                                            0 0 0 0
                                    >;
                            tx-num-evt = <1>;
                            rx-num-evt = <1>;
                    };
            };
    };
    

    谢谢你。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我不是Linux专家,但似乎您需要映射编解码器设置来禁用您的DTS不需要的通道/路径。

    让我与我们的Linux专家联系。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您能否尝试播放左声道和右声道使用不同内容的立体声曲目?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    是的,我播放了立体声曲目。 声音来自两个扬声器(左声道和右声道)。 我不确定如何确定左频道播放的内容是否与右频道不同。 对我来说,这两种声音几乎相同。  

    谢谢你。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您可以下载并安装Audacity,它可以编辑立体声曲目。简单测试,只需使用2个立体声曲目。第一个没有左声道信号,而第二个曲目没有右声道信号。您可以查看音频是否按预期输出。您可以搜索如何编辑曲目 Google上的Audacity。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您推荐此测试。 我就像你说的那样,用同一个立体声轨道创建了2个不同的立体声轨道:轨道1:无右声道信号,轨道2:无左声道信号。 下面是我观察到的:首先,当我播放曲目1时,声音来自两个扬声器(Spk1和Spk2)。 然后,当我播放曲目2时,声音来自两个扬声器。  但我希望Spk1 (连接到编解码器的左通道)仅播放Track1,而Spk2 (连接到编解码器的右通道)仅播放Track2。  请告诉我如何实现这一目标。

    是否必须调整某些寄存器设置,如使用i2cdump,i2cdet,i2cset等命令? 还是有更好的方法来做到这一点?

    谢谢你。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    让我更清楚地说明一下,我只想将编解码器的LET_LOP/M专用于一个应用程序(例如 分页)和Right_LOP/M (仅适用于其他(例如 内部通信)。 目前,我的问题是当我进行传呼时,两个扬声器都在播放呼叫。 预期的是,呼叫应仅从左声道扬声器(Spk1)播放。  

    希望这能澄清我的情况。

    谢谢你。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,

    使用i2cset禁用您不需要的频道,并相应地播放您的曲目。

    此致。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我尝试过,但音频仍然来自两个频道。 我甚至尝试禁用两个通道,但音频仍然来自这两个通道。 下面是dump命令(i2cdump -f -y 2 0x18)的结果。

    debian@am3358:~$ i2cdump -f -y 2 0x18
    No size specified (using byte-data access)
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
    00: 00 00 00 10 04 00 00 00 00 00 00 01 00 00 00 80    ...??......?...?
    10: 80 ff ff 78 78 78 78 78 78 06 00 fe 00 00 fe 00    ?..xxxxxx?.?..?.
    20: 00 00 00 00 00 00 00 00 00 00 00 80 80 00 00 00    ...........??...
    30: 00 00 00 04 00 00 00 00 00 00 04 00 00 00 00 00    ...?......?.....
    40: 00 04 00 00 00 00 00 00 04 00 00 00 00 00 00 00    .?......?.......
    50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    60: 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00    ......?.........
    70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    80: 00 00 00 10 04 00 00 00 00 00 00 01 00 00 00 80    ...??......?...?
    90: 80 ff ff 78 78 78 78 78 78 06 00 fe 00 00 fe 00    ?..xxxxxx?.?..?.
    a0: 00 00 00 00 00 00 00 00 00 00 00 80 80 00 00 00    ...........??...
    b0: 00 00 00 04 00 00 00 00 00 00 04 00 00 00 00 00    ...?......?.....
    c0: 00 04 00 00 00 00 00 00 04 00 00 00 00 00 00 00    .?......?.......
    d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    e0: 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00    ......?.........
    f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    

    如果我错过了什么,请告诉我。

    谢谢你。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    寄存器显示它们已禁用,因此寄存器转储不正确或设置中出现错误。

    我建议在播放音频时将左或右输出寄存器写为关,然后看到关闭它,如果这不起作用,可能意味着I2C 会被阻止,并且您不能读取i2cdump的正确寄存器。 您还可以监控I2C总线以查看 事务是否成功。

    此致。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    如果您指的是寄存器0x25,则是,默认为00。 我不知道为什么声音来自两个频道,即使它们都被禁用。 如果您正在讨论不同的注册表,请告诉我。  

    正如您所建议的(感谢您的想法),当我将00值写入Register 0x25或37 (十进制) 以在 播放音频时关闭左DAC和右DAC时,它确实关闭了它。 我使用的命令是i2cset -f -y 2 0x18 0x25 0x00。 我注意到,此操作后,寄存器值发生了很大变化(不仅是寄存器37,还有许多其他值)。 以下是此操作后的寄存器值:

    debian@am3358:~$ i2cdump -f -y 2 0x18
    No size specified (using byte-data access)
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
    00: 00 00 aa a0 04 00 00 1a c0 40 00 01 00 00 00 20    ..???..??@.?...
    10: 20 ff ff 00 78 78 00 78 78 06 00 fe 00 00 fe 00     ...xx.xx?.?..?.
    20: 00 00 00 00 00 00 00 00 00 00 00 07 07 00 2f af    ...........??./?
    30: 00 19 19 0f 00 2f af 00 12 12 0f 00 10 0f 00 2f    .???./?.???.??./
    40: af 0f 00 10 0f 00 2f af 0f 00 00 00 00 00 00 00    ??.??./??.......
    50: 00 08 08 00 00 87 0b 00 00 87 00 08 88 0b 1e 0c    .??..??..?.?????
    60: 00 00 00 00 00 01 02 00 00 00 00 00 00 00 00 00    .....??.........
    70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    80: 00 00 aa a0 04 00 00 1a c0 40 00 01 00 00 00 20    ..???..??@.?...
    90: 20 ff ff 00 78 78 00 78 78 06 00 fe 00 00 fe 00     ...xx.xx?.?..?.
    a0: 00 00 00 00 00 00 00 00 00 00 00 07 07 00 2f af    ...........??./?
    b0: 00 19 19 0f 00 2f af 00 12 12 0f 00 10 0f 00 2f    .???./?.???.??./
    c0: af 0f 00 10 0f 00 2f af 0f 00 00 00 00 00 00 00    ??.??./??.......
    d0: 00 08 08 00 00 87 0b 00 00 87 00 08 88 0b 1e 0c    .??..??..?.?????
    e0: 00 00 00 00 00 01 02 00 00 00 00 00 00 00 00 00    .....??.........
    f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................

    我不得不重新启动主板以恢复主板的寄存器值和其他功能,例如播放音频文件命令等

    有什么想法吗?

    谢谢你。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这表明某处正在控制编解码器路径,i2cdump可能不正确/不反映实际配置。

    我不是Linux专家,但在下面的DTS中,您有HP输出路由,但您需要的是左/右行,您需要在此处添加吗?

    此致。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您指出这一点。 但是,我确实尝试了DTS文件,正如你所说的那样,它有左/右行,但没有运气。 但主要的问题是,为什么左侧_LOP/M和右侧_LOP/M通道都输出音频,即使它们被i2cset命令强制禁用? 我使用TLV320AIC3104 EVM板获得了预期的结果。 但是当我在主板上尝试相同的i2c命令集时,它不起作用。

    Tests for TLV320AIC3104 EVM board
    -------------------------------------------------------------------
    Test 1: Both Left DAC and Right DAC are powered up
    Result: Audio coming from both (LEFT_LOP/M and RIGHT_LOP/M) channels
    
    w 30 07 8A
    w 30 25 C0
    w 30 29 02
    w 30 2B 00
    w 30 52 80
    w 30 5C 80
    w 30 4B 80
    w 30 4E 80
    w 30 56 09
    w 30 5D 09
    w 30 4F 09
    
    Test 2: Right DAC is powered up but Left DAC is NOT powered up
    Result: i)  Audio coming from RIGHT_LOP/M channel
            ii) Audio NOT coming from LEFT_LOP/M channel
    w 30 07 8A
    w 30 25 40
    w 30 29 02
    w 30 2B 00
    w 30 52 80
    w 30 5C 80
    w 30 4B 80
    w 30 4E 80
    w 30 56 09
    w 30 5D 09
    w 30 4F 09
    
    Test 3: Left DAC is powered up but Right DAC is NOT powered up
    Result: i)  Audio coming from LEFT_LOP/M channel
            ii) Audio NOT coming from RIGHT_LOP/M channel
    w 30 07 8A
    w 30 25 80
    w 30 29 02
    w 30 2B 00
    w 30 52 80
    w 30 5C 80
    w 30 4B 80
    w 30 4E 80
    w 30 56 09
    w 30 5D 09
    w 30 4F 09
    
    Test 4: None of the channels are powered up
    Result: Audio NOT coming any channel
    w 30 07 8A
    w 30 25 00
    w 30 29 02
    w 30 2B 00
    w 30 52 80
    w 30 5C 80
    w 30 4B 80
    w 30 4E 80
    w 30 56 09
    w 30 5D 09
    w 30 4F 09

    在定制BeagleBone黑色板上测试TLV320AIC3104

    ----------------------------------

    我使用i2cset命令(例如i2cset -f -y 2 0x18 0x25 0x40)分别运行了四个测试中的每一个。
    我在所有电路板寄存器(截至EVM板)中设置了精确值。 但是,在所有情况下,唯一发生的事情是两个信道都将音频输出。

    (注:我的编解码器的从属地址为0x18)。 如果您有任何想法,请提出建议。 我只需要将一个单声道音频信号路由到TLV320AIC3104编解码器的Left_LOP/M,另一个仅路由到Right_LOP/M。 我不在乎两个信号是同时路由还是在不同时间路由。

    请帮助。

    谢谢你。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    如果可以控制,则表示地址0x18正确。 您之前提到过,您可以通过i2cset关闭音频,因此本实验中的某些内容不正确。 我认为只需关注初始设置。  

    由于您可以使用i2cset关闭ALSA中的某个内容,因此我们无法控制这种情况,很遗憾,我们不是这方面的专家。

    此致。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    是的,我认为您是对的。 我还观察到,使用i2cset命令成功设置寄存器后,所有寄存器值在播放音频后都会自动重置。 看起来ALSA正在控制寄存器设置。 当我在ALSA (alsamixer)中更改设置时,更改会生效。 是否有办法告诉ALSA不要恢复我更改的寄存器设置?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    很遗憾,我们不是这方面的专家。

    我想知道您是否发现了这一点。

    此致。