You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
314 lines
7.7 KiB
314 lines
7.7 KiB
4 months ago
|
/*
|
||
|
* Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2020. All rights reserved.
|
||
|
* Description: mix engine sample
|
||
|
* Author: audio
|
||
|
* Create: 2019-05-19
|
||
|
*/
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
#include <pthread.h>
|
||
|
#include <unistd.h>
|
||
|
|
||
|
#include "uapi_sound.h"
|
||
|
#include "uapi_system.h"
|
||
|
#include "securec.h"
|
||
|
#include "adp_common_ext.h"
|
||
|
|
||
|
#define RATIO 1000
|
||
|
#define INPUT_CMD_LENGTH 32
|
||
|
|
||
|
typedef struct {
|
||
|
uapi_snd snd;
|
||
|
td_bool avc_enable;
|
||
|
uapi_snd_avc_attr avc_attr;
|
||
|
|
||
|
td_s32 argc;
|
||
|
td_char *argv[INPUT_CMD_LENGTH];
|
||
|
} sample_avc_ctx;
|
||
|
|
||
|
static td_void sample_avc_print_attr(sample_avc_ctx *ctx)
|
||
|
{
|
||
|
td_s32 ret;
|
||
|
|
||
|
ret = uapi_snd_get_avc_enable(ctx->snd, &ctx->avc_enable);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
printf("call uapi_snd_get_avc_enable failed(0x%x)\n", ret);
|
||
|
}
|
||
|
|
||
|
ret = uapi_snd_get_avc_attr(ctx->snd, &ctx->avc_attr);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
printf("call uapi_snd_get_avc_attr failed(0x%x)\n", ret);
|
||
|
}
|
||
|
|
||
|
printf("==========================================\n");
|
||
|
printf("-avc_enable: %s\n", (ctx->avc_enable == TD_TRUE) ? "yes" : "no");
|
||
|
|
||
|
printf("-attack_time: %d\n", ctx->avc_attr.attack_time);
|
||
|
printf("-release_time: %d\n", ctx->avc_attr.release_time);
|
||
|
|
||
|
printf("-threshold_level:%d.%ddB\n",
|
||
|
ctx->avc_attr.threshold_level / RATIO,
|
||
|
-ctx->avc_attr.threshold_level % RATIO);
|
||
|
|
||
|
printf("-gain:%d.%ddB\n",
|
||
|
ctx->avc_attr.gain / RATIO,
|
||
|
ctx->avc_attr.gain % RATIO);
|
||
|
|
||
|
printf("-limiter_level:%d.%ddB\n",
|
||
|
ctx->avc_attr.limiter_level / RATIO,
|
||
|
-ctx->avc_attr.limiter_level % RATIO);
|
||
|
|
||
|
printf("-ref_mode: %d\n", ctx->avc_attr.ref_mode);
|
||
|
printf("-speed_ctrl_mode: %d\n", ctx->avc_attr.speed_ctrl_mode);
|
||
|
|
||
|
printf("==========================================\n");
|
||
|
}
|
||
|
|
||
|
static td_void sample_avc_deinit(const sample_avc_ctx *ctx)
|
||
|
{
|
||
|
td_s32 ret;
|
||
|
|
||
|
ret = uapi_snd_deinit();
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
printf("call uapi_snd_deinit failed(0x%x)\n", ret);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static td_s32 sample_avc_init(sample_avc_ctx *ctx)
|
||
|
{
|
||
|
td_s32 ret;
|
||
|
|
||
|
ret = memset_s(ctx, sizeof(*ctx), 0, sizeof(sample_avc_ctx));
|
||
|
if (ret != EOK) {
|
||
|
printf("call memset_s failed(0x%x)\n", ret);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
ctx->snd = UAPI_SND_0;
|
||
|
|
||
|
ret = uapi_snd_init();
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
printf("call uapi_snd_init failed(0x%x)\n", ret);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
ret = uapi_snd_get_avc_enable(ctx->snd, &ctx->avc_enable);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
printf("call uapi_snd_get_avc_enable failed(0x%x)\n", ret);
|
||
|
goto out;
|
||
|
}
|
||
|
|
||
|
ret = uapi_snd_get_avc_attr(ctx->snd, &ctx->avc_attr);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
printf("call uapi_snd_get_avc_attr failed(0x%x)\n", ret);
|
||
|
goto out;
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
out:
|
||
|
sample_avc_deinit(ctx);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static td_void sample_avc_set_attr(sample_avc_ctx *ctx)
|
||
|
{
|
||
|
td_s32 ret;
|
||
|
|
||
|
ret = uapi_snd_set_avc_enable(ctx->snd, ctx->avc_enable);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
printf("call uapi_snd_set_avc_enable failed(0x%x)\n", ret);
|
||
|
}
|
||
|
|
||
|
ret = uapi_snd_set_avc_attr(ctx->snd, &ctx->avc_attr);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
printf("call uapi_snd_set_avc_attr failed(0x%x)\n", ret);
|
||
|
}
|
||
|
|
||
|
sample_avc_print_attr(ctx);
|
||
|
}
|
||
|
|
||
|
static td_void sample_avc_print_memu(td_void)
|
||
|
{
|
||
|
printf("==========================================\n");
|
||
|
printf("input q to quit\n");
|
||
|
printf("support option:\n");
|
||
|
printf(
|
||
|
"\t-p: print avc attr\n"
|
||
|
"\t-e: enable avc\n"
|
||
|
"\t-d: disable avc\n"
|
||
|
"\t-a: attack_time [20, 2000]\n"
|
||
|
"\t-r: release_time [20, 2000]\n"
|
||
|
"\t-t: threshold_level [-40.000, -16.000] dB\n"
|
||
|
"\t-g: gain [0, 8.000] dB\n"
|
||
|
"\t-l: limiter_level [-40.000, 0] dB\n"
|
||
|
"\t-f: ref_mode [0 or 1]\n"
|
||
|
"\t-s: speed_ctrl_mode [0 or 1]\n"
|
||
|
);
|
||
|
printf("==========================================\n");
|
||
|
}
|
||
|
|
||
|
static td_u32 sample_avc_parse_opt(sample_avc_ctx *ctx, td_char opt, td_char *opt_arg)
|
||
|
{
|
||
|
switch (opt) {
|
||
|
case 'h' | 'H':
|
||
|
sample_avc_print_memu();
|
||
|
return INPUT_CMD_LENGTH;
|
||
|
case 'e':
|
||
|
ctx->avc_enable = TD_TRUE;
|
||
|
return 1;
|
||
|
case 'd':
|
||
|
ctx->avc_enable = TD_FALSE;
|
||
|
return 1;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (opt_arg == TD_NULL) {
|
||
|
sample_avc_print_memu();
|
||
|
printf("invalid option -- '%c'\n", opt);
|
||
|
return INPUT_CMD_LENGTH;
|
||
|
}
|
||
|
|
||
|
switch (opt) {
|
||
|
case 'a':
|
||
|
ctx->avc_attr.attack_time = (td_u32)strtol(opt_arg, NULL, 10); /* 10 is Dec */
|
||
|
break;
|
||
|
case 'r':
|
||
|
ctx->avc_attr.release_time = (td_u32)strtol(opt_arg, NULL, 10); /* 10 is Dec */
|
||
|
break;
|
||
|
case 't':
|
||
|
ctx->avc_attr.threshold_level = (td_s32)(strtod(opt_arg, NULL) * RATIO);
|
||
|
break;
|
||
|
case 'g':
|
||
|
ctx->avc_attr.gain = (td_s32)(strtod(opt_arg, NULL) * RATIO);
|
||
|
break;
|
||
|
case 'l':
|
||
|
ctx->avc_attr.limiter_level = (td_s32)(strtod(opt_arg, NULL) * RATIO);
|
||
|
break;
|
||
|
case 'f':
|
||
|
ctx->avc_attr.ref_mode = !!strtol(opt_arg, NULL, 10); /* 10 is Dec */
|
||
|
break;
|
||
|
case 's':
|
||
|
ctx->avc_attr.speed_ctrl_mode = !!strtol(opt_arg, NULL, 10); /* 10 is Dec */
|
||
|
break;
|
||
|
default:
|
||
|
printf("invalid option -- '%c'\n", opt);
|
||
|
sample_avc_print_memu();
|
||
|
return INPUT_CMD_LENGTH;
|
||
|
}
|
||
|
|
||
|
return 2; /* consume 2 args */
|
||
|
}
|
||
|
|
||
|
static td_void sample_avc_cmd_line_to_arg(sample_avc_ctx *ctx, td_char *cmd, td_u32 cmd_size)
|
||
|
{
|
||
|
td_u32 i;
|
||
|
|
||
|
ctx->argc = 0;
|
||
|
ctx->argv[0] = TD_NULL;
|
||
|
|
||
|
if ((*cmd == '\0') || (*cmd == '\n')) {
|
||
|
sample_avc_print_memu();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < cmd_size; i++) {
|
||
|
if ((cmd[i] == ' ') || (cmd[i] == '\n')) {
|
||
|
cmd[i] = '\0';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < cmd_size; i++) {
|
||
|
if ((i == 0) && (cmd[i] != '\0')) {
|
||
|
ctx->argv[ctx->argc] = cmd + i;
|
||
|
ctx->argc++;
|
||
|
}
|
||
|
|
||
|
if ((i > 0) && (cmd[i - 1] == '\0') && (cmd[i] != '\0')) {
|
||
|
ctx->argv[ctx->argc] = cmd + i;
|
||
|
ctx->argc++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static td_void sample_avc_parse_cmd_line(sample_avc_ctx *ctx, td_char *cmd, td_u32 cmd_size)
|
||
|
{
|
||
|
td_u32 i;
|
||
|
td_u32 j;
|
||
|
|
||
|
sample_avc_cmd_line_to_arg(ctx, cmd, cmd_size);
|
||
|
|
||
|
if (ctx->argc == 0) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
i = 0;
|
||
|
|
||
|
while (1) {
|
||
|
if (i >= ctx->argc) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
j = sample_avc_parse_opt(ctx, *(ctx->argv[i]), ctx->argv[i + 1]);
|
||
|
if (j == INPUT_CMD_LENGTH) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
i += j;
|
||
|
}
|
||
|
|
||
|
sample_avc_set_attr(ctx);
|
||
|
}
|
||
|
|
||
|
td_s32 main(td_s32 argc, td_char *argv[])
|
||
|
{
|
||
|
td_s32 ret;
|
||
|
sample_avc_ctx ctx;
|
||
|
td_char input_cmd[INPUT_CMD_LENGTH];
|
||
|
|
||
|
ret = uapi_sys_init();
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
printf("call uapi_sys_init failed(0x%x)\n", ret);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
ret = sample_avc_init(&ctx);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
printf("call sample_avc_init failed(0x%x)\n", ret);
|
||
|
goto out;
|
||
|
}
|
||
|
|
||
|
sample_avc_print_attr(&ctx);
|
||
|
sample_avc_print_memu();
|
||
|
|
||
|
while (1) {
|
||
|
if (memset_s(input_cmd, sizeof(input_cmd),
|
||
|
0, INPUT_CMD_LENGTH) != EOK) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
(td_void)fgets((char *)(input_cmd), (sizeof(input_cmd) - 1), stdin);
|
||
|
|
||
|
if (input_cmd[0] == 'q') {
|
||
|
printf("prepare to quit!\n");
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
input_cmd[INPUT_CMD_LENGTH - 1] = '\0';
|
||
|
sample_avc_parse_cmd_line(&ctx, input_cmd, INPUT_CMD_LENGTH);
|
||
|
}
|
||
|
|
||
|
sample_avc_deinit(&ctx);
|
||
|
|
||
|
out:
|
||
|
ret = uapi_sys_deinit();
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
printf("call uapi_sys_deinit failed(0x%x)\n", ret);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|