/* * Copyright (c) CompanyNameMagicTag 2019-2020. All rights reserved. * Description: dpm sample * Author: audio * Create: 2019-09-17 */ #include #include #include #include "thread_os.h" #include "osal_list.h" #include "securec.h" #include "soc_uapi_adp.h" #include "soc_uapi_dpm.h" #include "dpm_fir_api.h" /* define DPM_PRINT_IN_OUT_DATA // macro to print input/output data define DPM_PRINT_INFO_LOG // macro to print info log define DPM_PRINT_PROC_TIME // macro to print proc cost time */ #ifndef EXT_SUCCESS #define EXT_SUCCESS 0 #define EXT_FAILURE (-1) #endif #define fir_printf printf #define fir_err_log_fun_err(func, err_code) fir_printf("[A][Error]Call %s Failed, Error Code: %#X\n", #func, err_code) #define fir_err_log_u32(val) fir_printf("[A][Error]%s = %u\n", #val, val) #ifndef DPM_PRINT_INFO_LOG #define fir_info_log_info(val) #define fir_info_log_u32(val) #else #define fir_info_log_info(val) fir_printf("[A][Info]<%s>\n", val) #define fir_info_log_u32(val) fir_printf("[A][Info]%s = %u\n", #val, val) #endif #ifndef DPM_PRINT_IN_OUT_DATA #define fir_log_s32(val) #define fir_log_u32(val) #define fir_log_dbl(val) #else #define fir_log_s32(val) fir_printf("%s = %d\n", #val, val) #define fir_log_u32(val) fir_printf("%s = %u\n", #val, val) #define fir_log_dbl(val) fir_printf("%s = %lf\n", #val, val) #endif #define DPM_FIR_DATA_SAMPLES_ALIGN 4 /* 4 : Requirement of fir algorithm process data num */ #define DPM_FIR_PROC_LOOP_SCALE_SHIFT 2 /* 2 : 2bits(4) for for loop process data num */ #define DPM_FIR_DEFAULT_FILTER_SAMPLES 1001 #define DPM_FIR_DEFAULT_DATA_SAMPLES 3001 #define DPM_ADP_BUF_RESERVED_SIZE 128 /* FIR input/output adp buf size, 128: reserved */ #define fir_align_up(size, align) (((size) + ((align) - 1)) & ~((align) - 1)) #include "dpm_fir_stat.h" #ifdef __cplusplus #if __cplusplus extern "C" { #endif #endif typedef struct { unsigned int block_len; /* length of sample block, should be a multiple of 4 */ unsigned int filter_len; /* length of filter, should be a multiple of 4 */ int *filter_coef; } dpm_fir_attr; typedef struct dpm_fir_inst { uapi_dpm_id dpm_id; unsigned int h_dpm; unsigned int h_adp_in; unsigned int h_adp_out; unsigned int data_samples; /* in/out data samples, x samples */ unsigned int coef_samples; /* filter coef samples, b samples */ struct osal_list_head node; } dpm_fir_inst; static OSAL_LIST_HEAD(g_dpm_list); static inline dpm_fir_inst *dpm_fir_alloc_inst(void) { dpm_fir_inst *inst = (dpm_fir_inst *)malloc(sizeof(dpm_fir_inst)); if (inst == NULL) { return NULL; } (void)memset_s(inst, sizeof(*inst), 0, sizeof(dpm_fir_inst)); osal_list_add_tail(&inst->node, &g_dpm_list); return inst; } static inline void dpm_fir_free_inst(dpm_fir_inst *inst) { if (inst == NULL) { return; } osal_list_del(&inst->node); free(inst); } static inline dpm_fir_inst *dpm_fir_get_inst(const dpm_fir_handle fir) { dpm_fir_inst *inst = TD_NULL; osal_list_for_each_entry(inst, &g_dpm_list, node) { if (inst == (dpm_fir_inst *)fir) { return inst; } } return TD_NULL; } #define FIR_B_QUANTIZER_NUM 2147483648 /* b参数定标31:放大2^31之后强转成int */ #define FIR_RAW_QUANTIZER_NUM 8192 /* x参数定标13:放大2^13之后强转成int */ static inline int dpm_fir_double_to_int(double in_data, unsigned int quantizer_num) { return (int)(in_data * (double)quantizer_num); } static inline double dpm_fir_int_to_double(int in_data, unsigned int quantizer_num) { return (double)in_data / (double)quantizer_num; } static int dpm_fir_sys_init(void) { int ret; ret = uapi_adp_init(); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(uapi_adp_init, ret); return ret; } ret = uapi_dpm_init(); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(uapi_dpm_init, ret); goto out; } return EXT_SUCCESS; out: (void)uapi_adp_deinit(); return ret; } static void dpm_fir_sys_deinit(void) { int ret; ret = uapi_dpm_deinit(); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(uapi_dpm_deinit, ret); } ret = uapi_adp_deinit(); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(uapi_adp_deinit, ret); } } static void dpm_fir_close_adp_input(dpm_fir_inst *inst) { int ret; if (inst->h_adp_in == 0) { return; } ret = uapi_adp_destroy(inst->h_adp_in); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(uapi_adp_destroy, ret); } inst->h_adp_in = 0; } static int dpm_fir_open_adp_input(dpm_fir_inst *inst) { int ret; int err; uapi_adp_attr adp_attr; inst->h_adp_in = 0; ret = uapi_adp_get_def_attr(&adp_attr); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(uapi_adp_get_def_attr, ret); goto out; } ret = uapi_adp_create(&inst->h_adp_in, &adp_attr); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(uapi_adp_create, ret); goto out; } return EXT_SUCCESS; out: inst->h_adp_in = 0; return ret; } static void dpm_close_adp_output(dpm_fir_inst *inst) { int ret; if (inst->h_adp_out == 0) { return; } ret = uapi_adp_destroy(inst->h_adp_out); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(uapi_adp_destroy, ret); } inst->h_adp_out = 0; } static int dpm_open_adp_output(dpm_fir_inst *inst) { int ret; uapi_adp_attr adp_attr; inst->h_adp_out = 0; ret = uapi_adp_get_def_attr(&adp_attr); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(uapi_adp_get_def_attr, ret); goto out; } ret = uapi_adp_create(&inst->h_adp_out, &adp_attr); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(uapi_adp_create, ret); goto out; } return EXT_SUCCESS; out: inst->h_adp_out = 0; return ret; } static void dpm_fir_close_dpm(dpm_fir_inst *inst) { int ret; if (inst->h_dpm == 0) { return; } ret = uapi_dpm_destroy(inst->h_dpm); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(uapi_dpm_destroy, ret); } inst->h_dpm = 0; } static int dpm_fir_attr_init(uapi_dpm_attr *dpm_attr, const dpm_fir_frame *coef_b, unsigned int coef_b_samples, unsigned int in_data_samples) { unsigned int i, loop_scale, data_cnt; int *fir_b = NULL; double *fir_b_dbl = NULL; dpm_fir_attr *fir_attr = NULL; dpm_attr->param.private_data_size = coef_b_samples * (unsigned int)sizeof(int) + (unsigned int)sizeof(dpm_fir_attr); dpm_attr->param.private_data = malloc(dpm_attr->param.private_data_size); if (dpm_attr->param.private_data == NULL) { fir_err_log_fun_err(malloc, EXT_ERR_DPM_FIR_MEM_ALLOC); return EXT_ERR_DPM_FIR_MEM_ALLOC; } fir_info_log_u32(dpm_attr->param.private_data_size); fir_attr = (dpm_fir_attr *)dpm_attr->param.private_data; fir_attr->block_len = in_data_samples; fir_attr->filter_len = coef_b_samples; if (coef_b->data_buffer == NULL) { return EXT_SUCCESS; } fir_b = (int *)&(fir_attr->filter_coef); fir_b_dbl = coef_b->data_buffer; /* Large for loop process data num : Align down to 4 */ data_cnt = coef_b->data_samples >> DPM_FIR_PROC_LOOP_SCALE_SHIFT << DPM_FIR_PROC_LOOP_SCALE_SHIFT; loop_scale = 1 << DPM_FIR_PROC_LOOP_SCALE_SHIFT; /* 1 : Initial num of for loop process data num */ fir_time_consume_start(); for (i = 0; i < data_cnt; i = i + loop_scale) { /* Trans from double to int */ fir_b[i] = dpm_fir_double_to_int(fir_b_dbl[i], FIR_B_QUANTIZER_NUM); fir_b[i + 1] = dpm_fir_double_to_int(fir_b_dbl[i + 1], FIR_B_QUANTIZER_NUM); /* 1 : Index shift of array */ fir_b[i + 2] = dpm_fir_double_to_int(fir_b_dbl[i + 2], FIR_B_QUANTIZER_NUM); /* 2 : Index shift of array */ fir_b[i + 3] = dpm_fir_double_to_int(fir_b_dbl[i + 3], FIR_B_QUANTIZER_NUM); /* 3 : Index shift of array */ } for (; i < coef_b->data_samples; i++) { /* Trans from double to int */ fir_b[i] = dpm_fir_double_to_int(fir_b_dbl[i], FIR_B_QUANTIZER_NUM); } data_cnt = (coef_b_samples - i) * (unsigned int)sizeof(*fir_b); (void)memset_s(&fir_b[i], data_cnt, 0, data_cnt); /* Add zero to align up to 4 */ fir_time_consume_stop("Coef b double to int"); #ifdef DPM_PRINT_IN_OUT_DATA for (i = 0; i < coef_b->data_samples; i++) { /* Logging coef b param of filter after transfer from double to int */ fir_log_s32(fir_b[i]); } #endif return EXT_SUCCESS; } static void dpm_fir_attr_deinit(uapi_dpm_attr *dpm_attr) { if (dpm_attr->param.private_data != NULL) { free(dpm_attr->param.private_data); } } static int dpm_fir_set_attr(dpm_fir_inst *inst, const dpm_fir_frame *coef_b) { int ret; uapi_dpm_attr dpm_attr; const uapi_adp_attr adp_attr = { .buf_size = inst->data_samples * (unsigned int)sizeof(int) + DPM_ADP_BUF_RESERVED_SIZE, }; ret = uapi_adp_set_attr(inst->h_adp_in, &adp_attr); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(uapi_adp_set_attr, ret); return ret; } ret = uapi_adp_set_attr(inst->h_adp_out, &adp_attr); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(uapi_adp_set_attr, ret); return ret; } dpm_attr.dpm_id = inst->dpm_id; dpm_attr.param.private_data_size = 0; dpm_attr.param.private_data = NULL; ret = dpm_fir_attr_init(&dpm_attr, coef_b, inst->coef_samples, inst->data_samples); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(dpm_fir_attr_init, ret); return ret; } fir_time_consume_start(); ret = uapi_dpm_set_attr(inst->h_dpm, &dpm_attr); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(uapi_dpm_set_attr, ret); return ret; } fir_time_consume_stop("uapi_dpm_set_attr"); dpm_fir_attr_deinit(&dpm_attr); return ret; } static void dpm_fir_data_prepare(int *fir_x, unsigned int x_samples, const dpm_fir_frame *in_frame) { int ret; unsigned int i, loop_scale, data_cnt; double *vector_x = in_frame->data_buffer; /* Large for loop process data num : Align down to 4 */ data_cnt = in_frame->data_samples >> DPM_FIR_PROC_LOOP_SCALE_SHIFT << DPM_FIR_PROC_LOOP_SCALE_SHIFT; loop_scale = 1 << DPM_FIR_PROC_LOOP_SCALE_SHIFT; /* 1 : Initial num of for loop process data num */ fir_time_consume_start(); for (i = 0; i < data_cnt; i = i + loop_scale) { fir_x[i] = dpm_fir_double_to_int(vector_x[i], FIR_RAW_QUANTIZER_NUM); fir_x[i + 1] = dpm_fir_double_to_int(vector_x[i + 1], FIR_RAW_QUANTIZER_NUM); /* 1 : Index shift of array */ fir_x[i + 2] = dpm_fir_double_to_int(vector_x[i + 2], FIR_RAW_QUANTIZER_NUM); /* 2 : Index shift of array */ fir_x[i + 3] = dpm_fir_double_to_int(vector_x[i + 3], FIR_RAW_QUANTIZER_NUM); /* 3 : Index shift of array */ } for (; i < in_frame->data_samples; i++) { fir_x[i] = dpm_fir_double_to_int(vector_x[i], FIR_RAW_QUANTIZER_NUM); } data_cnt = (x_samples - i) * (unsigned int)sizeof(*fir_x); (void)memset_s(&fir_x[i], data_cnt, 0, data_cnt); /* Add zero to align up to 4 */ fir_time_consume_stop("Input data double to int"); #ifdef DPM_PRINT_IN_OUT_DATA for (i = 0; i < in_frame->data_samples; i++) { /* Logging input data after transfer from double to int */ fir_log_s32(fir_x[i]); } #endif } static int dpm_fir_send_data(dpm_fir_inst *inst, const dpm_fir_frame *in_frame) { int ret; int *fir_x = NULL; double *vector_x = NULL; uapi_stream_buf stream = { 0 }; unsigned int i, loop_scale, data_cnt; const unsigned int in_data_size = inst->data_samples * (unsigned int)sizeof(int); if (in_frame->data_buffer == NULL) { fir_printf("in_frame->data_buffer null pointer\n"); return EXT_ERR_DPM_FIR_NULL_PTR; } ret = uapi_adp_get_buffer(inst->h_adp_in, &stream); if (ret != EXT_SUCCESS || stream.size < in_data_size) { fir_err_log_u32(stream.size); fir_err_log_u32(in_data_size); fir_err_log_fun_err(uapi_adp_get_buffer, ret); return ret; } /* Transfer input data from double to int && padding zeros to the end of input data */ dpm_fir_data_prepare((int *)stream.data, inst->data_samples, in_frame); stream.size = in_data_size; fir_info_log_u32(in_data_size); ret = uapi_adp_put_buffer(inst->h_adp_in, &stream); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(uapi_adp_put_buffer, ret); return ret; } return ret; } static int dpm_fir_data_post_proc(unsigned int coef_samples, unsigned char *out_buf, unsigned int out_buf_size, dpm_fir_frame *out_frame) { int *buf = NULL; double *fir_res = NULL; unsigned int i, loop_scale; unsigned int data_cnt = coef_samples / 2; /* 2 : Half of the coef b samples */ unsigned int busy_size = data_cnt * (unsigned int)sizeof(int); /* Data size of data cnt, samples to bytes */ const unsigned int out_data_size = out_frame->data_samples * (unsigned int)sizeof(int); if (out_frame->data_buffer == NULL) { fir_printf("out_frame->data_buffer null pointer\n"); return EXT_ERR_DPM_FIR_NULL_PTR; } if (busy_size >= out_buf_size) { fir_err_log_u32(busy_size); fir_err_log_u32(out_buf_size); fir_printf("Out data size && coef b size not matching\n"); return EXT_ERR_DPM_FIR_INVALID_PARAM; } buf = (int *)out_buf + data_cnt; /* Shift output data by skipping data_cnt samples at the begginning */ busy_size = out_buf_size - busy_size; /* Update out buf size for skipping busy_size at the begginning */ busy_size = busy_size < out_data_size ? busy_size : out_data_size; /* Set limit of output data size */ out_frame->data_samples = busy_size / (unsigned int)sizeof(int); /* Actual output data samples, bytes to samples */ /* Largest samples cnt for loop process data num : Align down to 4 */ data_cnt = out_frame->data_samples >> DPM_FIR_PROC_LOOP_SCALE_SHIFT << DPM_FIR_PROC_LOOP_SCALE_SHIFT; loop_scale = 1 << DPM_FIR_PROC_LOOP_SCALE_SHIFT; /* 1 : Initial num of for loop process data num */ fir_res = out_frame->data_buffer; fir_time_consume_start(); for (i = 0; i < data_cnt; i = i + loop_scale) { fir_res[i] = dpm_fir_int_to_double(buf[i], FIR_RAW_QUANTIZER_NUM); fir_res[i + 1] = dpm_fir_int_to_double(buf[i + 1], FIR_RAW_QUANTIZER_NUM); /* 1 : Index shift of array */ fir_res[i + 2] = dpm_fir_int_to_double(buf[i + 2], FIR_RAW_QUANTIZER_NUM); /* 2 : Index shift of array */ fir_res[i + 3] = dpm_fir_int_to_double(buf[i + 3], FIR_RAW_QUANTIZER_NUM); /* 3 : Index shift of array */ } for (; i < out_frame->data_samples; i++) { fir_res[i] = dpm_fir_int_to_double(buf[i], FIR_RAW_QUANTIZER_NUM); } fir_time_consume_stop("Output data int to double"); fir_info_log_u32(out_frame->data_samples); #ifdef DPM_PRINT_IN_OUT_DATA for (i = 0; i < out_frame->data_samples; i++) { /* Logging output data after transfer from int to double */ fir_log_dbl(fir_res[i]); } #endif return EXT_SUCCESS; } static int dpm_fir_recv_data(dpm_fir_inst *inst, dpm_fir_frame *out_frame) { int ret; unsigned int busy_size = 0; uapi_stream_buf stream = { 0 }; const unsigned int exp_data_size = inst->data_samples * (unsigned int)sizeof(int); fir_time_consume_start(); while (busy_size < exp_data_size) { ret = uapi_adp_query_busy(inst->h_adp_out, &busy_size); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(uapi_adp_query_busy, ret); return ret; } } fir_time_consume_stop("Wait for output data"); ret = uapi_adp_acquire_stream(inst->h_adp_out, &stream); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(uapi_adp_acquire_stream, ret); return ret; } /* Adjust data delay shift && transfer output from int to double */ ret = dpm_fir_data_post_proc(inst->coef_samples, stream.data, stream.size, out_frame); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(dpm_fir_data_post_proc, ret); } ret = uapi_adp_release_stream(inst->h_adp_out, &stream); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(uapi_adp_release_stream, ret); } return ret; } static void dpm_fir_param_update(dpm_fir_inst *inst, unsigned int coef_samples, unsigned int data_samples) { inst->coef_samples = fir_align_up(coef_samples, DPM_FIR_DATA_SAMPLES_ALIGN); /* Aligned to 4 */ /* 2 : Add half of coef b samples zeros to input data */ inst->data_samples = fir_align_up(data_samples, DPM_FIR_DATA_SAMPLES_ALIGN) + inst->coef_samples / 2; } static int dpm_fir_open_dpm(dpm_fir_inst *inst) { int ret; inst->h_dpm = 0; ret = uapi_dpm_create(&inst->h_dpm); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(uapi_dpm_create, ret); goto out; } return EXT_SUCCESS; out: inst->h_dpm = 0; return ret; } static void dpm_fir_close_inst(dpm_fir_inst *inst) { dpm_fir_close_adp_input(inst); dpm_fir_close_dpm(inst); dpm_close_adp_output(inst); dpm_fir_sys_deinit(); } static int dpm_fir_open_inst(dpm_fir_inst *inst) { int ret; ret = dpm_fir_sys_init(); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(dpm_fir_sys_init, ret); return ret; } /* Calc data/filter_coef samples with default config */ dpm_fir_param_update(inst, DPM_FIR_DEFAULT_FILTER_SAMPLES, DPM_FIR_DEFAULT_DATA_SAMPLES); /* * 数据流向 adp_in --> dpm --> adp_out * 按照数据流向反方向打开实例 * 按照数据方向attach output */ ret = dpm_open_adp_output(inst); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(dpm_open_adp_output, ret); goto out0; } ret = dpm_fir_open_dpm(inst); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(dpm_fir_open_dpm, ret); goto out1; } ret = dpm_fir_open_adp_input(inst); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(dpm_fir_open_adp_input, ret); goto out2; } return EXT_SUCCESS; out2: dpm_fir_close_dpm(inst); out1: dpm_close_adp_output(inst); out0: dpm_fir_sys_deinit(); return ret; } static void dpm_fir_stop_inst(dpm_fir_inst *inst) { int ret; ret = uapi_dpm_stop(inst->h_dpm); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(uapi_dpm_stop, ret); } } static int dpm_fir_start_inst(dpm_fir_inst *inst) { int ret; ret = uapi_dpm_start(inst->h_dpm); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(uapi_dpm_start, ret); } return ret; } static int dpm_fir_attach_inst(dpm_fir_inst *inst) { int ret; ret = uapi_adp_attach_output(inst->h_adp_in, inst->h_dpm); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(uapi_adp_attach_output, ret); return ret; } ret = uapi_dpm_attach_output(inst->h_dpm, inst->h_adp_out); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(uapi_dpm_attach_output, ret); return ret; } return ret; } static int dpm_fir_detach_inst(dpm_fir_inst *inst) { int ret; ret = uapi_adp_detach_output(inst->h_adp_in, inst->h_dpm); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(uapi_adp_detach_output, ret); return ret; } ret = uapi_dpm_detach_output(inst->h_dpm, inst->h_adp_out); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(uapi_dpm_detach_output, ret); return ret; } return ret; } int dpm_fir_init(dpm_fir_handle *fir) { int ret; dpm_fir_frame coef_b = { .data_buffer = NULL, }; dpm_fir_inst *inst = dpm_fir_get_inst(*fir); if (inst != NULL) { fir_printf("dpm fir is already running\n"); *fir = (dpm_fir_handle)inst; return EXT_ERR_DPM_FIR_INST_BUSY; } inst = dpm_fir_alloc_inst(); if (inst == NULL) { fir_printf("dpm_fir_alloc_inst failed\n"); return EXT_ERR_DPM_FIR_MEM_ALLOC; } inst->dpm_id = UAPI_DPM_ID_FIR; ret = dpm_fir_open_inst(inst); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(dpm_fir_open_inst, ret); goto out0; } coef_b.data_samples = inst->coef_samples; ret = dpm_fir_set_attr(inst, &coef_b); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(dpm_fir_set_attr, ret); return ret; } ret = dpm_fir_attach_inst(inst); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(dpm_fir_attach_inst, ret); return ret; } *fir = (dpm_fir_handle)inst; return EXT_SUCCESS; out0: dpm_fir_free_inst(inst); return ret; } int dpm_fir_deinit(const dpm_fir_handle fir) { int ret; dpm_fir_inst *inst = dpm_fir_get_inst(fir); if (inst != NULL) { dpm_fir_stop_inst(inst); ret = dpm_fir_detach_inst(inst); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(dpm_fir_detach_inst, ret); return ret; } dpm_fir_close_inst(inst); dpm_fir_free_inst(inst); } return EXT_SUCCESS; } int dpm_fir_set_coef(const dpm_fir_handle fir, const dpm_fir_frame *coef_a, const dpm_fir_frame *coef_b, unsigned int input_data_samples) { int ret; dpm_fir_inst *inst = dpm_fir_get_inst(fir); if (inst == NULL) { fir_printf("dpm fir is not running\n"); return EXT_ERR_DPM_FIR_NOT_AVAILABLE; } if (coef_b == NULL) { fir_printf("input param has null pointer\n"); return EXT_ERR_DPM_FIR_NULL_PTR; } dpm_fir_stop_inst(inst); ret = dpm_fir_detach_inst(inst); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(dpm_fir_detach_inst, ret); return ret; } /* Calc data/filter_coef samples with default config */ dpm_fir_param_update(inst, coef_b->data_samples, input_data_samples); fir_info_log_u32(inst->coef_samples); fir_info_log_u32(inst->data_samples); ret = dpm_fir_set_attr(inst, coef_b); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(dpm_fir_set_attr, ret); return ret; } ret = dpm_fir_attach_inst(inst); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(dpm_fir_attach_inst, ret); return ret; } (void)coef_a; return EXT_SUCCESS; } int dpm_fir_proc(const dpm_fir_handle fir, const dpm_fir_frame *in_frame, dpm_fir_frame *out_frame) { int ret; dpm_fir_inst *inst = dpm_fir_get_inst(fir); if (inst == NULL) { fir_printf("dpm fir is not running\n"); return EXT_ERR_DPM_FIR_NOT_AVAILABLE; } if (in_frame == NULL || out_frame == NULL) { fir_printf("input param has null pointer\n"); return EXT_ERR_DPM_FIR_NULL_PTR; } ret = dpm_fir_start_inst(inst); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(dpm_fir_start_inst, ret); return ret; } /* Update samples of input data according to in_frame; 2 : Add half of coef b samples zeros to input data */ inst->data_samples = fir_align_up(in_frame->data_samples, DPM_FIR_DATA_SAMPLES_ALIGN) + inst->coef_samples / 2; ret = dpm_fir_send_data(inst, in_frame); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(dpm_fir_send_data, ret); return ret; } ret = dpm_fir_recv_data(inst, out_frame); if (ret != EXT_SUCCESS) { fir_err_log_fun_err(dpm_fir_recv_data, ret); return ret; } dpm_fir_stop_inst(inst); return EXT_SUCCESS; } #ifdef __cplusplus #if __cplusplus } #endif #endif