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

/*
* 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;
}