/* * Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2020. All rights reserved. * Description: mix engine sample * Author: audio * Create: 2019-05-19 */ #include #include #include #include #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; }