/* * 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 "securec.h" #include "uapi_sound.h" #include "uapi_system.h" #include "adp_common_ext.h" #define RATIO 1000 #define INPUT_CMD_LENGTH 32 typedef struct { uapi_snd snd; td_bool drc_enable; uapi_snd_out_port out_port; uapi_snd_drc_attr drc_attr; td_s32 argc; td_char *argv[INPUT_CMD_LENGTH]; } sample_drc_ctx; static const struct { uapi_snd_out_port port; const td_char *name; } g_ao_port_name[] = { { UAPI_SND_OUT_PORT_DAC0, "DAC0" }, { UAPI_SND_OUT_PORT_I2S0, "I2S0" }, { UAPI_SND_OUT_PORT_I2S1, "I2S1" }, { UAPI_SND_OUT_PORT_I2S2, "I2S2" }, { UAPI_SND_OUT_PORT_I2S3, "I2S3" }, { UAPI_SND_OUT_PORT_I2S4, "I2S4" }, { UAPI_SND_OUT_PORT_SPDIF0, "SPDIF0" }, { UAPI_SND_OUT_PORT_HDMITX0, "HDMI0" }, { UAPI_SND_OUT_PORT_HDMITX1, "HDMI1" }, { UAPI_SND_OUT_PORT_ARC0, "ARC0" }, { UAPI_SND_OUT_PORT_DAC1, "DAC1" }, { UAPI_SND_OUT_PORT_DAC2, "DAC2" }, { UAPI_SND_OUT_PORT_DAC3, "DAC3" }, { UAPI_SND_OUT_PORT_ALL, "ALLPORT" }, }; static const td_char *autil_port_to_name(uapi_snd_out_port port) { td_u32 i; for (i = 0; i < (sizeof(g_ao_port_name) / sizeof(g_ao_port_name[0])); i++) { if (port == g_ao_port_name[i].port) { return g_ao_port_name[i].name; } } return "unknown_port"; } static uapi_snd_out_port autil_port_name_to_port(const td_char *name) { td_u32 i; for (i = 0; i < (sizeof(g_ao_port_name) / sizeof(g_ao_port_name[0])); i++) { if (strncmp(name, g_ao_port_name[i].name, strlen(g_ao_port_name[i].name)) == 0) { return g_ao_port_name[i].port; } } return UAPI_SND_OUT_PORT_MAX; } static td_void sample_drc_print_attr(sample_drc_ctx *drc_ctx) { td_s32 ret; ret = uapi_snd_get_drc_enable(drc_ctx->snd, drc_ctx->out_port, &drc_ctx->drc_enable); if (ret != TD_SUCCESS) { printf("call uapi_snd_get_drc_enable failed(0x%x)\n", ret); } ret = uapi_snd_get_drc_attr(drc_ctx->snd, drc_ctx->out_port, &drc_ctx->drc_attr); if (ret != TD_SUCCESS) { printf("call uapi_snd_get_drc_attr failed(0x%x)\n", ret); } printf("==========================================\n"); printf("-out_port: %s\n", autil_port_to_name(drc_ctx->out_port)); printf("-drc_enable: %s\n", (drc_ctx->drc_enable == TD_TRUE) ? "yes" : "no"); printf("-attack_time: %d\n", drc_ctx->drc_attr.attack_time); printf("-release_time: %d\n", drc_ctx->drc_attr.release_time); printf("-threshold:%d.%ddB\n", drc_ctx->drc_attr.thrhd / RATIO, -drc_ctx->drc_attr.thrhd % RATIO); printf("-limit:%d.%ddB\n", drc_ctx->drc_attr.limit / RATIO, drc_ctx->drc_attr.limit % RATIO); printf("-ref_mode: %d\n", drc_ctx->drc_attr.ref_mode); printf("-speed_ctrl_mode: %d\n", drc_ctx->drc_attr.speed_ctrl_mode); printf("==========================================\n"); } static td_void sample_drc_deinit(const sample_drc_ctx *drc_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_drc_init(sample_drc_ctx *drc_ctx) { td_s32 ret; ret = memset_s(drc_ctx, sizeof(*drc_ctx), 0, sizeof(sample_drc_ctx)); if (ret != EOK) { printf("call memset_s failed(0x%x)\n", ret); return ret; } drc_ctx->snd = UAPI_SND_0; drc_ctx->out_port = UAPI_SND_OUT_PORT_DAC0; ret = uapi_snd_init(); if (ret != TD_SUCCESS) { printf("call uapi_snd_init failed(0x%x)\n", ret); return ret; } ret = uapi_snd_get_drc_enable(drc_ctx->snd, drc_ctx->out_port, &drc_ctx->drc_enable); if (ret != TD_SUCCESS) { printf("call uapi_snd_get_drc_enable failed(0x%x)\n", ret); goto out; } ret = uapi_snd_get_drc_attr(drc_ctx->snd, drc_ctx->out_port, &drc_ctx->drc_attr); if (ret != TD_SUCCESS) { printf("call uapi_snd_get_drc_attr failed(0x%x)\n", ret); goto out; } return TD_SUCCESS; out: sample_drc_deinit(drc_ctx); return ret; } static td_void sample_drc_set_attr(sample_drc_ctx *drc_ctx) { td_s32 ret; ret = uapi_snd_set_drc_enable(drc_ctx->snd, drc_ctx->out_port, drc_ctx->drc_enable); if (ret != TD_SUCCESS) { printf("call uapi_snd_set_drc_enable failed(0x%x)\n", ret); } ret = uapi_snd_set_drc_attr(drc_ctx->snd, drc_ctx->out_port, &drc_ctx->drc_attr); if (ret != TD_SUCCESS) { printf("call uapi_snd_set_drc_attr failed(0x%x)\n", ret); } sample_drc_print_attr(drc_ctx); } static td_void sample_drc_print_memu(td_void) { printf("==========================================\n"); printf("input q to quit\n"); printf("support option:\n"); printf( "\t-p: print drc attr\n" "\t-o: select out port(DAC0/I2S0/HDMI0/SPDIF0)\n" "\t-e: enable drc\n" "\t-d: disable drc\n" "\t-a: attack_time [20, 2000]\n" "\t-r: release_time [20, 2000]\n" "\t-t: threshold [-80.000, -1.000] dB\n" "\t-l: limit [-80.000, -1.000] dB\n" "\t-f: ref_mode [0 or 1]\n" "\t-s: speed_ctrl_mode [0 or 1]\n"); printf("==========================================\n"); } static td_s32 sample_drc_parse_attr(sample_drc_ctx *drc_ctx, td_char opt, const td_char *opt_arg) { if (opt_arg == TD_NULL) { printf("invalid option -- '%c'\n", opt); sample_drc_print_memu(); return TD_FAILURE; } switch (opt) { case 'o': drc_ctx->out_port = autil_port_name_to_port(opt_arg); break; case 'a': drc_ctx->drc_attr.attack_time = (td_u32)strtol(opt_arg, NULL, 10); /* 10 is Dec */ break; case 'r': drc_ctx->drc_attr.release_time = (td_u32)strtol(opt_arg, NULL, 10); /* 10 is Dec */ break; case 't': drc_ctx->drc_attr.thrhd = (td_s32)(strtod(opt_arg, NULL) * RATIO); break; case 'l': drc_ctx->drc_attr.limit = (td_s32)(strtod(opt_arg, NULL) * RATIO); break; case 'f': drc_ctx->drc_attr.ref_mode = !!strtol(opt_arg, NULL, 10); /* 10 is Dec */ break; case 's': drc_ctx->drc_attr.speed_ctrl_mode = !!strtol(opt_arg, NULL, 10); /* 10 is Dec */ break; default: printf("invalid option -- '%c'\n", opt); sample_drc_print_memu(); return TD_FAILURE; } return TD_SUCCESS; } static td_u32 sample_drc_parse_opt(sample_drc_ctx *drc_ctx, td_char opt, const td_char *opt_arg) { td_s32 ret; switch (opt) { case 'h' | 'H': sample_drc_print_memu(); return INPUT_CMD_LENGTH; case 'p' | 'P': sample_drc_print_attr(drc_ctx); return INPUT_CMD_LENGTH; case 'e': drc_ctx->drc_enable = TD_TRUE; return 1; case 'd': drc_ctx->drc_enable = TD_FALSE; return 1; default: break; } ret = sample_drc_parse_attr(drc_ctx, opt, opt_arg); if (ret != TD_SUCCESS) { return INPUT_CMD_LENGTH; } return 2; /* consume 2 args */ } static td_void sample_drc_cmd_line_to_arg(sample_drc_ctx *drc_ctx, td_char *cmd, td_u32 cmd_size) { td_u32 i; drc_ctx->argc = 0; drc_ctx->argv[0] = TD_NULL; if ((*cmd == '\0') || (*cmd == '\n')) { sample_drc_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')) { drc_ctx->argv[drc_ctx->argc] = cmd + i; drc_ctx->argc++; } if ((i > 0) && (cmd[i - 1] == '\0') && (cmd[i] != '\0')) { drc_ctx->argv[drc_ctx->argc] = cmd + i; drc_ctx->argc++; } } } static td_void sample_drc_parse_cmd_line(sample_drc_ctx *drc_ctx, td_char *cmd, td_u32 cmd_size) { td_u32 i; td_u32 j; drc_ctx->argc = 0; sample_drc_cmd_line_to_arg(drc_ctx, cmd, cmd_size); if (drc_ctx->argc == 0) { return; } i = 0; while (1) { if (i >= drc_ctx->argc) { break; } j = sample_drc_parse_opt(drc_ctx, *(drc_ctx->argv[i]), drc_ctx->argv[i + 1]); if (j == INPUT_CMD_LENGTH) { return; } i += j; } sample_drc_set_attr(drc_ctx); } td_s32 main(td_s32 argc, td_char *argv[]) { td_s32 ret; sample_drc_ctx drc_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_drc_init(&drc_ctx); if (ret != TD_SUCCESS) { printf("call sample_drc_init failed(0x%x)\n", ret); goto out; } sample_drc_print_attr(&drc_ctx); sample_drc_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_drc_parse_cmd_line(&drc_ctx, input_cmd, INPUT_CMD_LENGTH); } sample_drc_deinit(&drc_ctx); out: ret = uapi_sys_deinit(); if (ret != TD_SUCCESS) { printf("call uapi_sys_deinit failed(0x%x)\n", ret); return ret; } return 0; }