首页 > 其他分享 >RK3588 tinyalsa_hal添加一个自定义声卡输入和输出

RK3588 tinyalsa_hal添加一个自定义声卡输入和输出

时间:2024-07-20 11:00:11浏览次数:15  
标签:SOUND SND hal 自定义 dev 声卡 card CARD out

一、添加输出声卡

输出流程图:

在声卡列表snd_out_sound_cards里添加一个自己的声卡,比如

--- a/tinyalsa_hal/audio_hw.h
+++ b/tinyalsa_hal/audio_hw.h
@@ -216,6 +216,7 @@ enum snd_out_sound_cards {
     SND_OUT_SOUND_CARD_SPDIF,
     SND_OUT_SOUND_CARD_SPDIF_1,
     SND_OUT_SOUND_CARD_BT,
+    SND_OUT_SOUND_CARD_UAC,
     SND_OUT_SOUND_CARD_MAX,
 };

//这里声卡数量也要加1
--- a/tinyalsa_hal/audio_hw.c
+++ b/tinyalsa_hal/audio_hw.c
@@ -62,8 +62,8 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <ctype.h>
-#define SNDRV_CARDS 8
-#define SNDRV_DEVICES 8
+#define SNDRV_CARDS 9
+#define SNDRV_DEVICES 9

添加一个dev_proc_info

参考一下rk的speaker:

自定义声卡为:

--- a/tinyalsa_hal/audio_hw.c
+++ b/tinyalsa_hal/audio_hw.c
@@ -407,9 +410,17 @@ struct dev_proc_info SPEAKER_OUT_NAME[] = /* add codes& dai name here*/
     {"rockchiprt5672c", NULL,},
     {"rk3528acodec",    NULL},
     {"rockchipdummyco",    NULL},
     {NULL, NULL}, /* Note! Must end with NULL, else will cause crash */
 };
 
+struct dev_proc_info UAC_OUT_NAME[] =
+{
+    {"UAC2Gadget",    NULL},//这里填写实际的声卡名。用cat /proc/asound/cards查看
+    {NULL, NULL}, /* Note! Must end with NULL, else will cause crash */
+};
+
+

将声卡添加到输出流中:

根据上面的输出流程图,首先会调用adev_open_output_stream这个函数来打开要配置输出声卡,

write配置为out_write

最终是调用了start_output_stream函数

在 read_out_sound_card函数里面获取声卡id添加到dev_out中

@@ -781,6 +792,7 @@ static void read_out_sound_card(struct stream_out *out)
         get_specified_out_dev(&device->dev_out[SND_OUT_SOUND_CARD_SPDIF], card, id, SPDIF_OUT_NAME);
         get_specified_out_dev(&device->dev_out[SND_OUT_SOUND_CARD_SPDIF_1],card, id, SPDIF_1_OUT_NAME);
         get_specified_out_dev(&device->dev_out[SND_OUT_SOUND_CARD_BT], card, id, BT_OUT_NAME);
+               get_specified_out_dev(&device->dev_out[SND_OUT_SOUND_CARD_UAC], card, id, UAC_OUT_NAME);
     }
     dumpdev_info("out", device->dev_out, SND_OUT_SOUND_CARD_MAX);
     return ;
@@ -1164,6 +1176,20 @@ static int start_output_stream(struct stream_out *out)
             device = adev->dev_out[SND_OUT_SOUND_CARD_SPEAKER].device;
             ret = open_pcm(card, device, (int)SND_OUT_SOUND_CARD_SPEAKER, out);
             if (ret <  0) return ret;
+                       /**添加UAC声卡播放音频**/
+                       char value[PROPERTY_VALUE_MAX];
+                       property_get("persist.sys.uac_speak_output", value, "0");
+                   int uac_speak_output = atoi(value);
                    if(uac_speak_output == 1)
+                       {
+                               card = adev->dev_out[SND_OUT_SOUND_CARD_UAC].card;
+               device = adev->dev_out[SND_OUT_SOUND_CARD_UAC].device;
+                               if(card != (int)SND_OUT_SOUND_CARD_UNKNOWN)
+                               {
+                                       ret = open_pcm(card, device, (int)SND_OUT_SOUND_CARD_UAC, out);
+                                       if (ret < 0) return ret;
+                   }
+                       }
   

通过配置属性persist.sys.uac_speak_output为1声卡就可以播放音频

二、添加输入声卡

输入流程图

添加输入声卡与上述输出声卡的步骤类似,这里贴上对应的补丁:

diff --git a/tinyalsa_hal/audio_hw.h b/tinyalsa_hal/audio_hw.h
index aeade30..ba7cb38 100755
--- a/tinyalsa_hal/audio_hw.h
+++ b/tinyalsa_hal/audio_hw.h
@@ -225,6 +236,9 @@ enum snd_in_sound_cards {
     SND_IN_SOUND_CARD_MIC = 0,
     SND_IN_SOUND_CARD_BT,
     SND_IN_SOUND_CARD_HDMI,
+    SND_IN_SOUND_CARD_LT6911UXE,
     SND_IN_SOUND_CARD_MAX,
};
--- a/tinyalsa_hal/audio_hw.c
+++ b/tinyalsa_hal/audio_hw.c
@@ -485,6 +485,28 @@ struct dev_proc_info MIC_IN_NAME[] =
     {NULL, NULL}, /* Note! Must end with NULL, else will cause crash */
 };
+struct dev_proc_info LT6911UXE_IN_NAME[] =
+{
+	{"soundlt6911uxe", NULL},
+	{NULL, NULL}, /* Note! Must end with NULL, else will cause crash */
+};
@@ -834,10 +856,15 @@ static void read_in_sound_card(struct stream_in *in)
             len--;
            id[len] = '\0';
         }
+		ALOGD("MIC card%d id:%s", card, id);
         get_specified_in_dev(&device->dev_in[SND_IN_SOUND_CARD_MIC], card, id, MIC_IN_NAME);
         /* set HDMI audio input info if need hdmi audio input */
         get_specified_in_dev(&device->dev_in[SND_IN_SOUND_CARD_HDMI], card, id, HDMI_IN_NAME);
         get_specified_in_dev(&device->dev_in[SND_IN_SOUND_CARD_BT], card, id, BT_IN_NAME);
+		get_specified_in_dev(&device->dev_in[SND_IN_SOUND_CARD_LT6911UXE], card, id, LT6911UXE_IN_NAME);
     }
     dumpdev_info("in", device->dev_in, SND_IN_SOUND_CARD_MAX);
     return ;
@@ -1481,11 +1508,31 @@ static int start_input_stream(struct stream_in *in)
       } else {
         ALOGD("open build mic");
         in->config = &pcm_config_in;
-        card = adev->dev_in[SND_IN_SOUND_CARD_MIC].card;
-        device =  adev->dev_in[SND_IN_SOUND_CARD_MIC].device;
+
+		/**根据系统属性选择不同的声卡**/
+		char mic_value[PROPERTY_VALUE_MAX];
+		property_get("persist.sys.mic", mic_value, "0");
+		if (strcmp(mic_value, "soundlt6911uxe") == 0) {
+       		card = adev->dev_in[SND_IN_SOUND_CARD_LT6911UXE].card;
+        	device =  adev->dev_in[SND_IN_SOUND_CARD_LT6911UXE].device;
+			ALOGD("mic_value is LT6911UXE: card = %d,device = %d",card,device);
+       }
         if (card != SND_IN_SOUND_CARD_UNKNOWN) {
-            route_pcm_card_open(card, getRouteFromDevice(in->device | AUDIO_DEVICE_BIT_IN));
+            //route_pcm_card_open(card, getRouteFromDevice(in->device | AUDIO_DEVICE_BIT_IN));
             in->pcm = pcm_open(card, device, PCM_IN, in->config);
         }

 @@ -4260,6 +4307,9 @@ static void adev_open_init(struct audio_device *adev)
         	adev->dev_out[SND_OUT_SOUND_CARD_UAC].id = "UAC";
     adev->dev_in[SND_IN_SOUND_CARD_MIC].id = "MIC";
     adev->dev_in[SND_IN_SOUND_CARD_BT].id = "BT";
+	adev->dev_in[SND_IN_SOUND_CARD_DUMMY].id = "LT6911UXE";
     adev->owner[0] = NULL;
     adev->owner[1] = NULL;

标签:SOUND,SND,hal,自定义,dev,声卡,card,CARD,out
From: https://blog.csdn.net/qq_54089476/article/details/140566531

相关文章

  • Datawhale AI 夏令营——电力需求挑战赛——Task3学习笔记
        这一期学习进阶的特征提取与分析,构建深度学习方案,拿下更高分数,冲冲冲。项目链接:‌​​‬​‍​​​‌​‬‬⁠​​⁠​⁠​​​​⁠​​‍​​‍​​‌⁠‬​⁠​⁠‍‌​‌​​‍​Task3:尝试使用深度学习方案-飞书云文档(feishu.cn)    前两期介绍了......
  • Java关于注解的使用、如何自定义注解、如何通过元注解解析注解
    注解的介绍Java中总共有五大引用数据类型:类、数组、接口、枚举、注解。其中注解是在jdk1.5版本中加进来的特性,和类,接口,枚举是同一个层次的。注解应用:说明:一般用来对代码进行说明,方便生成doc文档(API文档)检查:检查代码是否符合条件@Override(检查重写方法)@FunctionalInter......
  • YOLOV8自定义数据集训练过程中遇到的问题
    书接上回,在弄好了Labelimg了以后,便开始了图像的标注。按照官网推荐的格式,建好文件夹。文件夹格式:dataset下为train和val两个文件夹,两个文件夹中的内容均为images和labels。images里放的就是图像了,labels为标注的数据。接下里就是创建自己的yaml文件,文件的内容指定数据集的根......
  • Datawhale AI 夏令营 task2语言包陷入困境
     一、了解机器翻译在运行task1时,我仅仅只是按照教程一步步走下去,不理解每一步的意义,也不懂什么叫做机器翻译。于是在task2中碰了壁。1.机器翻译的含义机器翻译(MT)是自然语言处理领域的一个重要分支,其目标是将一种语言的文本自动转换为另一种语言的文本。机器翻译的发展经历......
  • EeayDecode:解码合约的自定义错误、事件和函数参数与返回值
    官网:easydecode.dev还在为解码合约自定义错误事件和函数参数与返回值而苦恼吗?快试试easydecode吧!只需提供合约ABI即可快速、方便的解码合约的自定义错误、事件和函数参数与返回值。1.解码Event将Event的Topics(字符串数组,使用,分割)和Data填入输入框,点击“DecodeE......
  • EXCEL:按有序列表对数组进行排序,无需自定义列表
    我有一张邮政编码表,其中包含发送到每个邮政编码的货件数量。我想按特定顺序按邮政编码对这个数组进行排序,我将其放在第二个列表中。我不想按客户数量或邮政编码的数字顺序排序,而是按这个专门排名的列表排序。我无法使用自定义排序功能,因为我的列表对于此功能来说太长了。......
  • 国产linux系统(银河麒麟,统信uos)使用 PageOffice 国产版在线打开 word文件自定义模板中
    国产linux系统(银河麒麟,统信uos)使用PageOffice国产版在线打开pdf文件PageOffice国产版:支持信创系统,支持银河麒麟V10和统信UOS,支持X86(intel、兆芯、海光等)、ARM(飞腾、鲲鹏、麒麟等)芯片架构。本示例关键代码的编写位置Vue+Springboot注意本文中展示的代码均为关键代码,复......
  • vxe-grid 自定义工具栏,去掉原来的工具栏
    1、如果要自定义那么就少不了slots了2、代码<vxe-gridref="tableRef"v-bind="gridOptions":folding-all="true"><template#toolbar_buttons><Selectv-model:value="searchForm.fieldname&......
  • echarts自定义胶囊柱图并设置每个柱子的渐变色
    drawCharts(){letmyChart=echarts.init(document.getElementById('main'));letoption={tooltip:{trigger:'axis',axisPointer:{type:'line'}......
  • 自定义异常
    了解手动抛出异常对象和自动抛出thrownew异常类的对象throws异常类对象,两者区别throw在方法中用throws在声明时用使用场景多个方法并列,可以使用throw自定义异常继承于现有的异常体系。通常继承于RuntimeException\Exception通常提供几个重载的构造器提供一个全......