/* * 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_system.h" #include "uapi_sound.h" #include "adp_common_ext.h" #define RATIO 1000 #define INPUT_CMD_LENGTH 32 typedef struct { uapi_snd snd; td_bool peq_enable; uapi_snd_out_port out_port; td_u32 select_band; uapi_snd_peq_attr peq_attr; td_s32 argc; td_char *argv[INPUT_CMD_LENGTH]; } sample_peq_ctx; static const struct { uapi_snd_out_port out_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_HDMITX0, "HDMI0" }, { UAPI_SND_OUT_PORT_HDMITX1, "HDMI1" }, { UAPI_SND_OUT_PORT_SPDIF0, "SPDIF0" }, { 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 out_port) { td_u32 i; for (i = 0; i < (sizeof((g_ao_port_name)) / sizeof((g_ao_port_name)[0])); i++) { if (out_port == g_ao_port_name[i].out_port) { return g_ao_port_name[i].name; } } return "n/a"; } static uapi_snd_out_port autil_port_name_to_port(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].out_port; } } return UAPI_SND_OUT_PORT_MAX; } static const struct { uapi_peq_filter_type filter_type; const td_char *name; } g_peq_filter_type_name[] = { {UAPI_PEQ_FILTER_TYPE_HP, "HP"}, {UAPI_PEQ_FILTER_TYPE_LS, "LS"}, {UAPI_PEQ_FILTER_TYPE_PK, "PK"}, {UAPI_PEQ_FILTER_TYPE_HS, "HS"}, {UAPI_PEQ_FILTER_TYPE_LP, "LP"}, }; static const td_char *autil_peq_type_to_name(uapi_peq_filter_type filter_type) { if (filter_type < (sizeof((g_peq_filter_type_name)) / sizeof((g_peq_filter_type_name)[0]))) { return g_peq_filter_type_name[filter_type].name; } return "n/a"; } static td_void sample_peq_print_attr(sample_peq_ctx *peq_ctx) { td_u32 i; td_s32 ret; peq_ctx->peq_enable = TD_FALSE; ret = uapi_snd_get_peq_enable(peq_ctx->snd, peq_ctx->out_port, &peq_ctx->peq_enable); if (ret != TD_SUCCESS) { printf("call uapi_snd_get_peq_enable failed(0x%x)\n", ret); return; } ret = uapi_snd_get_peq_attr(peq_ctx->snd, peq_ctx->out_port, &peq_ctx->peq_attr); if (ret != TD_SUCCESS) { printf("call uapi_snd_get_peq_attr failed(0x%x)\n", ret); return; } printf("==========================================\n"); printf("-out_port: %s\n", autil_port_to_name(peq_ctx->out_port)); printf("-peq_enable: %s\n", (peq_ctx->peq_enable == TD_TRUE) ? "yes" : "no"); printf("-band_num: %d\n", peq_ctx->peq_attr.band_num); printf("%4s | %-11s | %-6s | %-3s | %-5s |\n", "band", "filter_type", "freq", "q", "gain"); for (i = 0; i < peq_ctx->peq_attr.band_num; i++) { printf("%4d | %4d %-6s %-6d %-3d %-5d |\n", i, peq_ctx->peq_attr.param[i].filter_type, autil_peq_type_to_name(peq_ctx->peq_attr.param[i].filter_type), peq_ctx->peq_attr.param[i].freq, peq_ctx->peq_attr.param[i].q, peq_ctx->peq_attr.param[i].gain); } printf("-select_band: %d\n", peq_ctx->select_band); printf("\n==========================================\n"); } static td_void sample_peq_deinit(sample_peq_ctx *peq_ctx) { td_s32 ret; (td_void)peq_ctx; ret = uapi_snd_deinit(); if (ret != TD_SUCCESS) { printf("call uapi_snd_deinit failed(0x%x)\n", ret); return; } } static td_s32 sample_peq_init(sample_peq_ctx *peq_ctx) { td_s32 ret; ret = memset_s(peq_ctx, sizeof(*peq_ctx), 0, sizeof(sample_peq_ctx)); if (ret != EOK) { printf("call memset_s failed(0x%x)\n", ret); return ret; } peq_ctx->snd = UAPI_SND_0; peq_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_peq_enable(peq_ctx->snd, peq_ctx->out_port, &peq_ctx->peq_enable); if (ret != TD_SUCCESS) { printf("call uapi_snd_get_peq_enable failed(0x%x)\n", ret); goto out; } ret = uapi_snd_get_peq_attr(peq_ctx->snd, peq_ctx->out_port, &peq_ctx->peq_attr); if (ret != TD_SUCCESS) { printf("call uapi_snd_get_peq_attr failed(0x%x)\n", ret); goto out; } return TD_SUCCESS; out: sample_peq_deinit(peq_ctx); return ret; } static td_void sample_peq_set_attr(sample_peq_ctx *peq_ctx) { td_s32 ret; ret = uapi_snd_set_peq_enable(peq_ctx->snd, peq_ctx->out_port, peq_ctx->peq_enable); if (ret != TD_SUCCESS) { printf("call uapi_snd_set_peq_enable failed(0x%x)\n", ret); } ret = uapi_snd_set_peq_attr(peq_ctx->snd, peq_ctx->out_port, &peq_ctx->peq_attr); if (ret != TD_SUCCESS) { printf("call uapi_snd_set_peq_attr failed(0x%x)\n", ret); } ret = uapi_snd_get_peq_enable(peq_ctx->snd, peq_ctx->out_port, &peq_ctx->peq_enable); if (ret != TD_SUCCESS) { printf("call uapi_snd_get_peq_enable failed(0x%x)\n", ret); } ret = uapi_snd_get_peq_attr(peq_ctx->snd, peq_ctx->out_port, &peq_ctx->peq_attr); if (ret != TD_SUCCESS) { printf("call uapi_snd_get_peq_attr failed(0x%x)\n", ret); } sample_peq_print_attr(peq_ctx); } static td_void sample_peq_print_memu(td_void) { printf("==========================================\n"); printf("input q to quit\n"); printf("support option:\n"); printf( "\t-p: print peq attr\n" "\t-o: select out port(DAC0/I2S0/HDMI0/SPDIF0)\n" "\t-e: enable peq\n" "\t-d: disable peq\n" "\t-b: set total num of banks [1, 10]\n" "\t-n: select bank to change attr [0, 9]\n" "\t-t: filter type(HP:0, LS:1, PK:2, HS:3, LP:4)\n" "\t-f: freq(HP and LS[20, 4000], PK[20, 22000], HS[4000, 22000], LP[50, 22000])\n" "\t-q: Q value(HS and LS[7, 10], PK[5, 100], HP and LP is fix to be 7)\n" "\t-g: gain(-15000, 15000, step by 125)\n" ); printf("==========================================\n"); } static td_s32 sample_peq_parse_attr(sample_peq_ctx *peq_ctx, td_char opt, td_char *opt_arg) { if (opt_arg == TD_NULL) { printf("invalid option -- '%c'\n", opt); sample_peq_print_memu(); return TD_FAILURE; } if (peq_ctx->peq_attr.band_num > UAPI_SND_EQ_BAND_MAX) { printf("invalid band_num -- '%d'\n", peq_ctx->peq_attr.band_num); sample_peq_print_memu(); return TD_FAILURE; } if (peq_ctx->select_band >= UAPI_SND_EQ_BAND_MAX) { printf("invalid select_band -- '%d'\n", peq_ctx->select_band); sample_peq_print_memu(); return TD_FAILURE; } switch (opt) { case 'o': peq_ctx->out_port = autil_port_name_to_port(opt_arg); break; case 'b': peq_ctx->peq_attr.band_num = (td_u32)strtol(opt_arg, NULL, 10); /* 10 is Dec */ break; case 'n': peq_ctx->select_band = (td_u32)strtol(opt_arg, NULL, 10); /* 10 is Dec */ break; case 't': peq_ctx->peq_attr.param[peq_ctx->select_band].filter_type = (uapi_peq_filter_type)strtol(opt_arg, NULL, 10); /* 10 is Dec */ break; case 'f': peq_ctx->peq_attr.param[peq_ctx->select_band].freq = (td_u32)strtol(opt_arg, NULL, 10); /* 10 is Dec */ break; case 'q': peq_ctx->peq_attr.param[peq_ctx->select_band].q = (td_u32)strtol(opt_arg, NULL, 10); /* 10 is Dec */ break; case 'g': peq_ctx->peq_attr.param[peq_ctx->select_band].gain = (td_u32)strtol(opt_arg, NULL, 10); /* 10 is Dec */ break; default: printf("invalid option -- '%c'\n", opt); sample_peq_print_memu(); return TD_FAILURE; } return TD_SUCCESS; } static td_u32 sample_peq_parse_opt(sample_peq_ctx *peq_ctx, td_char opt, td_char *opt_arg) { td_s32 ret; switch (opt) { case 'h' | 'H': sample_peq_print_memu(); return INPUT_CMD_LENGTH; case 'p' | 'P': sample_peq_print_attr(peq_ctx); return INPUT_CMD_LENGTH; case 'e': peq_ctx->peq_enable = TD_TRUE; return 1; case 'd': peq_ctx->peq_enable = TD_FALSE; return 1; default: break; } ret = sample_peq_parse_attr(peq_ctx, opt, opt_arg); if (ret != TD_SUCCESS) { return INPUT_CMD_LENGTH; } return 2; /* consume 2 args */ } static td_void sample_peq_cmd_line_to_arg(sample_peq_ctx *peq_ctx, td_char *cmd, td_u32 cmd_size) { td_u32 j; peq_ctx->argc = 0; peq_ctx->argv[0] = TD_NULL; if ((*cmd == '\0') || (*cmd == '\n')) { sample_peq_print_memu(); return; } for (j = 0; j < cmd_size; j++) { if ((cmd[j] == ' ') || (cmd[j] == '\n')) { cmd[j] = '\0'; } } for (j = 0; j < cmd_size; j++) { if ((j == 0) && (cmd[j] != '\0')) { peq_ctx->argv[peq_ctx->argc] = cmd + j; peq_ctx->argc++; } if ((j > 0) && (cmd[j - 1] == '\0') && (cmd[j] != '\0')) { peq_ctx->argv[peq_ctx->argc] = cmd + j; peq_ctx->argc++; } } } static td_void sample_peq_parse_cmd_line(sample_peq_ctx *peq_ctx, td_char *cmd, td_u32 cmd_size) { td_s32 i; td_s32 j; sample_peq_cmd_line_to_arg(peq_ctx, cmd, cmd_size); if (peq_ctx->argc == 0) { return; } i = 0; while (1) { if (i >= peq_ctx->argc) { break; } j = sample_peq_parse_opt(peq_ctx, *(peq_ctx->argv[i]), peq_ctx->argv[i + 1]); if (j == INPUT_CMD_LENGTH) { return; } i += j; } sample_peq_set_attr(peq_ctx); } td_s32 main(td_s32 argc, td_char *argv[]) { td_s32 ret; sample_peq_ctx peq_ctx; td_char input_cmd[INPUT_CMD_LENGTH]; (td_void)argc; (td_void)argv; ret = uapi_sys_init(); if (ret != TD_SUCCESS) { printf("call uapi_sys_init failed(0x%x)\n", ret); return ret; } ret = sample_peq_init(&peq_ctx); if (ret != TD_SUCCESS) { printf("call sample_peq_init failed(0x%x)\n", ret); goto out; } sample_peq_print_attr(&peq_ctx); sample_peq_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_peq_parse_cmd_line(&peq_ctx, input_cmd, INPUT_CMD_LENGTH); } sample_peq_deinit(&peq_ctx); out: ret = uapi_sys_deinit(); if (ret != TD_SUCCESS) { printf("call uapi_sys_deinit failed(0x%x)\n", ret); return ret; } return 0; }