RK3568平台(音频篇)TinyAlsa集成第三方音频算法

一.tinyalsa介绍

ALSA(Advanced Linux Sound Architecture)是一个开源项目,涵盖了用户空间和内核空间对音频设备的操作接口,通过应用层使用alsalib可以实现对音频设备的控制

        TinyAlsa是android推出的一个精简的ALSA库,当然alsa-driver这块没有改动

        alsa包含:1、内核 alsa-driver 2.用户空间 alsa-lib(android使用的TinyAlsa)

二.使用tinyplay测试音频

tinycap /data/test.wav -D pdm声卡号   -d 0 -c 10 -r 48000 -b 16 -p 1024 -n 4    //D 后面接pdm声卡的声卡号

三.在TinyAlsa集成第三方音频降

tinyalsa目录:

hardware\rockchip\audio\tinyalsa_hal\

第三方算法供应商提供的音频降噪算法so库:

修改Android:


LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := libElevocMeetingVoice
+LOCAL_SRC_FILES_32 := lib_out_honghe/armeabi-v7a/libElevocMeetingVoice.so
+LOCAL_SRC_FILES_64 := lib_out_honghe/arm64-v8a/libElevocMeetingVoice.so
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_MODULE_SUFFIX := .so
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MULTILIB := both
include $(BUILD_PREBUILT)

include $(CLEAR_VARS)

LOCAL_MODULE := audio.primary.$(TARGET_BOARD_HARDWARE)
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_SRC_FILES := \
	bitstream/audio_iec958.c \
	bitstream/audio_bitstream.c \
	bitstream/audio_bitstream_manager.c \
	audio_hw.c \
	alsa_route.c \
	alsa_mixer.c \
	voice_preprocess.c \
	audio_hw_hdmi.c \
	out_honghe.c \
	denoise/rkdenoise.c

LOCAL_C_INCLUDES += \
	$(call include-path-for, audio-utils) \
	$(call include-path-for, audio-route) \
	$(call include-path-for, speex)

LOCAL_CFLAGS += -Wno-error

+LOCAL_SHARED_LIBRARIES := liblog libcutils libaudioutils libaudioroute +libhardware_legacy libspeexresampler libElevocMeetingVoice

#API 31 -> Android 12.0, Android 12.0 link libtinyalsa_iec958
ifneq (1, $(strip $(shell expr $(PLATFORM_SDK_VERSION) \< 31)))
LOCAL_SHARED_LIBRARIES += libtinyalsa_iec958
else
LOCAL_SHARED_LIBRARIES += libtinyalsa
endif

ifeq ($(strip $(BOARD_SUPPORT_MULTIAUDIO)), true)
LOCAL_CFLAGS += -DSUPPORT_MULTIAUDIO
endif

LOCAL_STATIC_LIBRARIES := libspeex
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_CFLAGS += -Wno-error
LOCAL_SRC_FILES:= amix.c alsa_mixer.c
LOCAL_MODULE:= amix
LOCAL_PROPRIETARY_MODULE := true
LOCAL_SHARED_LIBRARIES := liblog libc libcutils
include $(BUILD_EXECUTABLE)

这样降噪音频算法so就集成在Android里面了。

一般算法供应商会提供调用的算法的demo供我们集成在tinyalsa里面。

四.使用算法供应商提供的demo测试音频

main.cpp:

//#include <stdio.h>
#include <string>
#include <math.h>
#include <vector>
#include <sstream>
#include <fstream>
#include <algorithm>
#include <memory>
#include <iostream>
#include <time.h>
//#include "wav_io.h"
#include "ElevocAIOTProcess.h"

#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#include <sys/time.h>
#endif
#include <chrono>
using namespace std;
#define ELEV_FRMAE_SIZE 256
#define ELEV_MIC_NUM 8

#define ELEV_REF_NUM 2
#define ELEV_ALL_NUM (ELEV_MIC_NUM+ELEV_REF_NUM)

static const char* fname_mdl = "./model-1477000--11.475842399597168_export_convert_mdl_q16.EM2";
void test_short(){
	ELEVOC_AIOT_PROCESS* p = elevoc_aiot_init(fname_mdl);

	string record_filePath = "./";
	string input_path = record_filePath + "in.pcm";// "testg12_6ch_230815.raw";// "testg12_230815.raw";//  "testg12.raw"; //"testg12.raw";

	FILE* ifp = fopen(input_path.c_str(), "rb");
	size_t input_size = 0;
	if (ifp != NULL) {
		if (!fseek(ifp, 0, SEEK_END)) {
			input_size = ftell(ifp);
			fseek(ifp, 0, SEEK_SET);
		}
	}
	else {
		fprintf(stderr, "file open error\n");
	}
	printf("samplers : %zd\n", input_size / sizeof(float));

	string outPath = record_filePath + "out.pcm";


	FILE* pFout = fopen(outPath.c_str(), "wb");

	size_t once_read = ELEV_FRMAE_SIZE * ELEV_ALL_NUM;
	size_t left_size = input_size / sizeof(int16_t);
	size_t readSize = 0;

	int16_t readBuffer[ELEV_FRMAE_SIZE * ELEV_ALL_NUM];
	int16_t outputBuffer[ELEV_FRMAE_SIZE];
	int16_t output[ELEV_FRMAE_SIZE];

	printf("start ...\n");
	clock_t start, finish;
	double total_time;
	int frm = 0;
#ifdef COUNT_ELAPSE
    double elapseSum = 0;
    double maxElapse = 0;
    double minElapse = 100;
#endif
	while (true) {
		frm++;
		/*if (frm>=63*114)
		{
		printf("debug\n");
		}*/
		readSize = left_size < once_read ? left_size : once_read;
		if (readSize < once_read) {
			break;
		}
		fread(readBuffer, sizeof(int16_t), once_read, ifp);

		//start = clock();
#ifdef COUNT_ELAPSE
        auto startTime = std::chrono::system_clock::now();
#endif
        printf("guyilian elevoc_aiot_process_short start ...\n");
		elevoc_aiot_process_short(p, readBuffer, once_read* sizeof(short), outputBuffer);
		printf("guyilian elevoc_aiot_process_short end ...\n");

#ifdef COUNT_ELAPSE
        auto endTime = std::chrono::system_clock::now();
        std::chrono::duration<double, std::milli> elapse = endTime - startTime;
        double elapseDouble = elapse.count();
        if (elapseDouble > maxElapse) {
            maxElapse = elapseDouble;
        }
        if (minElapse > elapseDouble) {
            minElapse = elapseDouble;
        }
        elapseSum += elapseDouble;
#endif
		//finish = clock();
		//long total_time = (finish - start);
		//printf("time %ld msec \n", total_time);
		for (int i = 0; i < ELEV_FRMAE_SIZE; i++)
		{
			output[i] = (int16_t)(outputBuffer[i] * 1);
		}
		fwrite(output, sizeof(int16_t), ELEV_FRMAE_SIZE, pFout);
		left_size -= readSize;
	}
#ifdef COUNT_ELAPSE
    std::printf("each frame process avg = cost %f ms ,[min = %f][max = %f] \n",
                elapseSum / (double)frm, minElapse, maxElapse);
#endif
	printf("end ...\n");

	fclose(pFout);
}


int main() {
	//test();
	test_short();
	system("PAUSE");
	return 0;
}

Android: 



LOCAL_PATH := $(call my-dir)

LOCAL_C_INCLUDES += \
    elemain/ElevocAIOTProcess.h

include $(CLEAR_VARS)
LOCAL_CFLAGS += -Wno-error
LOCAL_SRC_FILES := \
	main.cpp
LOCAL_MODULE:= elemain
LOCAL_PROPRIETARY_MODULE := true
LOCAL_SHARED_LIBRARIES := liblog libc libcutils libElevocMeetingVoice
include $(BUILD_EXECUTABLE)

这样测试demo会被编译成可执行文件elemain。

  • 10
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
RK3568是一款芯片,主要用于智能设备和嵌入式系统。在RK3568的设置中,默认启动第三方桌面可以通过以下步骤实现。 首先,我们需要进入RK3568的设置界面。可以通过点击设备的设置图标或者在应用程序列表中找到设置应用来进入设置界面。 在设置界面中,我们需要找到"显示"或"桌面"这样的选项。不同设备可能会有不同的设置界面结构,但一般来说,我们可以通过滚动或点击不同的选项卡来找到我们需要的选项。 在"显示"或"桌面"选项中,我们可以找到"默认桌面"这样的选项。点击进入该选项后,我们就可以看到当前选择的桌面。 默认情况下,RK3568可能会预设一个自带的桌面作为默认桌面。如果我们希望启动第三方桌面,我们可以在"默认桌面"选项中选择我们喜欢的第三方桌面应用。 RK3568可能会提供一些常见的第三方桌面应用供选择,比如Nova Launcher、Microsoft Launcher等。如果我们已经在设备中安装了其他第三方桌面应用,我们也可以在这里选择该应用作为默认桌面。 选择了第三方桌面后,我们可以返回到设备的主屏幕并重新启动设备。此时,我们就可以看到选择的第三方桌面已经成为默认启动的桌面。 请注意,不同的设备和操作系统版本可能会有不同的设置界面布局和选项名称。如果在设置中找不到类似的选项,可以参考设备的用户手册或在互联网上搜索相关的设置指南。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式_笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值