1245 lines
35 KiB
C
1245 lines
35 KiB
C
|
/***************************************************************************
|
||
|
*
|
||
|
* Copyright 2015-2019 BES.
|
||
|
* All rights reserved. All unpublished rights reserved.
|
||
|
*
|
||
|
* No part of this work may be used or reproduced in any form or by any
|
||
|
* means, or stored in a database or retrieval system, without prior written
|
||
|
* permission of BES.
|
||
|
*
|
||
|
* Use of this work is governed by a license granted by BES.
|
||
|
* This work contains confidential and proprietary information of
|
||
|
* BES. which is protected by copyright, trade secret,
|
||
|
* trademark and other intellectual property rights.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
/*******************************************************************************
|
||
|
** namer : Audio Process
|
||
|
** description : Manage auido process algorithms, include :hw iir eq, sw iir eq,
|
||
|
** hw fir eq, drc...
|
||
|
** version : V1.0
|
||
|
** author : Yunjie Huo
|
||
|
** modify : 2018.12.4
|
||
|
** todo : NULL
|
||
|
** MIPS : NO PROCESS: 34M(TWS, one ear, Mono, AAC, 48k)
|
||
|
** DRC1: 36M(3 bands)
|
||
|
** DRC2: 12M
|
||
|
*******************************************************************************/
|
||
|
/*
|
||
|
Audio Flow:
|
||
|
DECODE --> SW IIR EQ --> DRC --> LIMTER --> VOLUME --> HW IIR EQ --> SPK
|
||
|
|
||
|
+-----------------------------+
|
||
|
| DAC |
|
||
|
| |
|
||
|
+--------+ +-----------+ +-----+ +--------+ | +--------+ +-----------+ | +-----+
|
||
|
| | PCM | | | | | | | | | | | | | |
|
||
|
| DECODE +---->+ SW IIR EQ +--->+ DRC +--->+ LIMTER +--->+ VOLUME +--->+ HW IIR EQ +--->+ SPK |
|
||
|
| | | | | | | | | | | | | | | |
|
||
|
+--------+ +-----------+ +-----+ +--------+ | +--------+ +-----------+ | +-----+
|
||
|
+-----------------------------+
|
||
|
|
||
|
| ------------ | ------------------------- | -------- | ----------- |
|
||
|
| Algorithm | description | MIPS(M) | RAM(kB) |
|
||
|
| ------------ | ------------------------- | -------- | ----------- |
|
||
|
| DRC | Dynamic Range Compression | 12M/band | 13 |
|
||
|
| Limiter/DRC2 | Limiter | 12M | 5 |
|
||
|
| EQ | Equalizer | 1M/band | Almost zero |
|
||
|
*/
|
||
|
|
||
|
#include "hal_timer.h"
|
||
|
#include "hal_trace.h"
|
||
|
#include "hal_cmu.h"
|
||
|
#include "string.h"
|
||
|
#include "audio_process.h"
|
||
|
#include "stdbool.h"
|
||
|
#include "hal_location.h"
|
||
|
#include "hw_codec_iir_process.h"
|
||
|
#include "hw_iir_process.h"
|
||
|
#include "tgt_hardware.h"
|
||
|
#include "drc.h"
|
||
|
#include "limiter.h"
|
||
|
#include "audio_cfg.h"
|
||
|
|
||
|
#if defined(USB_EQ_TUNING)
|
||
|
#if !defined(__HW_DAC_IIR_EQ_PROCESS__) && !defined(__SW_IIR_EQ_PROCESS__)
|
||
|
#error "Either HW_DAC_IIR_EQ_PROCESS or SW_IIR_EQ_PROCESS should be defined when enabling USB_EQ_TUNING"
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
#if defined(__PC_CMD_UART__) || defined(USB_EQ_TUNING)
|
||
|
#include "hal_cmd.h"
|
||
|
|
||
|
#if defined(__SW_IIR_EQ_PROCESS__)
|
||
|
#define AUDIO_EQ_SW_IIR_UPDATE_CFG
|
||
|
#endif
|
||
|
|
||
|
#if defined(__HW_DAC_IIR_EQ_PROCESS__)
|
||
|
#define AUDIO_EQ_HW_DAC_IIR_UPDATE_CFG
|
||
|
#endif
|
||
|
|
||
|
#if defined(__HW_IIR_EQ_PROCESS__)
|
||
|
#define AUDIO_EQ_HW_IIR_UPDATE_CFG
|
||
|
#endif
|
||
|
|
||
|
#ifdef __HW_FIR_EQ_PROCESS__
|
||
|
#define AUDIO_EQ_HW_FIR_UPDATE_CFG
|
||
|
#endif
|
||
|
|
||
|
#ifdef __AUDIO_DRC__
|
||
|
#define AUDIO_DRC_UPDATE_CFG
|
||
|
#endif
|
||
|
|
||
|
#ifdef __AUDIO_DRC2__
|
||
|
#define AUDIO_DRC2_UPDATE_CFG
|
||
|
#endif
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#if defined(__SW_IIR_EQ_PROCESS__)
|
||
|
extern const IIR_CFG_T * const audio_eq_sw_iir_cfg_list[EQ_SW_IIR_LIST_NUM];
|
||
|
#endif
|
||
|
|
||
|
#if defined(__HW_DAC_IIR_EQ_PROCESS__)
|
||
|
extern const IIR_CFG_T * const POSSIBLY_UNUSED audio_eq_hw_dac_iir_cfg_list[EQ_HW_DAC_IIR_LIST_NUM];
|
||
|
#endif
|
||
|
|
||
|
#if defined(__HW_IIR_EQ_PROCESS__)
|
||
|
extern const IIR_CFG_T * const POSSIBLY_UNUSED audio_eq_hw_iir_cfg_list[EQ_HW_IIR_LIST_NUM];
|
||
|
#endif
|
||
|
|
||
|
#ifdef __HW_FIR_EQ_PROCESS__
|
||
|
extern const FIR_CFG_T * const audio_eq_hw_fir_cfg_list[EQ_HW_FIR_LIST_NUM];
|
||
|
#endif
|
||
|
|
||
|
#ifdef __AUDIO_DRC__
|
||
|
extern const DrcConfig audio_drc_cfg;
|
||
|
#endif
|
||
|
|
||
|
#ifdef __AUDIO_DRC2__
|
||
|
extern const LimiterConfig audio_drc2_cfg;
|
||
|
#endif
|
||
|
|
||
|
#if defined(AUDIO_EQ_SW_IIR_UPDATE_CFG) || defined(AUDIO_EQ_HW_FIR_UPDATE_CFG)|| defined(AUDIO_EQ_HW_DAC_IIR_UPDATE_CFG)|| defined(AUDIO_EQ_HW_IIR_UPDATE_CFG) || defined(AUDIO_DRC_UPDATE_CFG) || defined(AUDIO_DRC2_UPDATE_CFG)
|
||
|
#define AUDIO_UPDATE_CFG
|
||
|
#endif
|
||
|
|
||
|
#ifdef __AUDIO_DRC__
|
||
|
#define AUDIO_DRC_NEEDED_SIZE (1024*13)
|
||
|
#else
|
||
|
#define AUDIO_DRC_NEEDED_SIZE (0)
|
||
|
#endif
|
||
|
|
||
|
#ifdef __AUDIO_DRC2__
|
||
|
#define AUDIO_DRC2_NEEDED_SIZE (1024*5)
|
||
|
#else
|
||
|
#define AUDIO_DRC2_NEEDED_SIZE (0)
|
||
|
#endif
|
||
|
|
||
|
#define AUDIO_MEMORY_SIZE (AUDIO_DRC_NEEDED_SIZE + AUDIO_DRC2_NEEDED_SIZE)
|
||
|
|
||
|
#if AUDIO_MEMORY_SIZE > 0
|
||
|
#include "audio_memory.h"
|
||
|
#endif
|
||
|
|
||
|
#ifndef CODEC_OUTPUT_DEV
|
||
|
#define CODEC_OUTPUT_DEV CFG_HW_AUD_OUTPUT_PATH_SPEAKER_DEV
|
||
|
#endif
|
||
|
|
||
|
typedef signed int pcm_24bits_t;
|
||
|
typedef signed short int pcm_16bits_t;
|
||
|
|
||
|
typedef struct{
|
||
|
enum AUD_BITS_T sample_bits;
|
||
|
enum AUD_SAMPRATE_T sample_rate;
|
||
|
enum AUD_CHANNEL_NUM_T sw_ch_num;
|
||
|
enum AUD_CHANNEL_NUM_T hw_ch_num;
|
||
|
|
||
|
#if defined(__SW_IIR_EQ_PROCESS__)
|
||
|
bool sw_iir_enable;
|
||
|
#endif
|
||
|
|
||
|
#if defined(__HW_DAC_IIR_EQ_PROCESS__)
|
||
|
bool hw_dac_iir_enable;
|
||
|
#endif
|
||
|
|
||
|
#if defined(__HW_IIR_EQ_PROCESS__)
|
||
|
bool hw_iir_enable;
|
||
|
#endif
|
||
|
|
||
|
#if defined(__HW_FIR_EQ_PROCESS__)
|
||
|
bool hw_fir_enable;
|
||
|
#endif
|
||
|
|
||
|
#if AUDIO_MEMORY_SIZE > 0
|
||
|
uint8_t *audio_heap;
|
||
|
#endif
|
||
|
|
||
|
#ifdef __AUDIO_DRC__
|
||
|
DrcState *drc_st;
|
||
|
#endif
|
||
|
|
||
|
#ifdef __AUDIO_DRC2__
|
||
|
LimiterState *drc2_st;
|
||
|
#endif
|
||
|
|
||
|
#ifdef AUDIO_UPDATE_CFG
|
||
|
bool update_cfg;
|
||
|
#endif
|
||
|
|
||
|
#ifdef USB_EQ_TUNING
|
||
|
bool eq_updated_cfg;
|
||
|
#endif
|
||
|
|
||
|
|
||
|
#ifdef AUDIO_EQ_SW_IIR_UPDATE_CFG
|
||
|
IIR_CFG_T sw_iir_cfg;
|
||
|
#endif
|
||
|
|
||
|
#ifdef AUDIO_EQ_HW_DAC_IIR_UPDATE_CFG
|
||
|
IIR_CFG_T hw_dac_iir_cfg;
|
||
|
#endif
|
||
|
|
||
|
#ifdef AUDIO_EQ_HW_IIR_UPDATE_CFG
|
||
|
IIR_CFG_T hw_iir_cfg;
|
||
|
#endif
|
||
|
|
||
|
#ifdef AUDIO_EQ_HW_FIR_UPDATE_CFG
|
||
|
FIR_CFG_T hw_fir_cfg;
|
||
|
#endif
|
||
|
|
||
|
#ifdef AUDIO_DRC_UPDATE_CFG
|
||
|
bool drc_update;
|
||
|
DrcConfig drc_cfg;
|
||
|
#endif
|
||
|
|
||
|
#ifdef AUDIO_DRC2_UPDATE_CFG
|
||
|
bool drc2_update;
|
||
|
LimiterConfig drc2_cfg;
|
||
|
#endif
|
||
|
} AUDIO_PROCESS_T;
|
||
|
|
||
|
static AUDIO_PROCESS_T audio_process = {
|
||
|
.sample_bits = AUD_BITS_NULL,
|
||
|
.sample_rate = AUD_SAMPRATE_NULL,
|
||
|
.sw_ch_num = AUD_CHANNEL_NUM_NULL,
|
||
|
.hw_ch_num = AUD_CHANNEL_NUM_NULL,
|
||
|
|
||
|
#if defined(__SW_IIR_EQ_PROCESS__)
|
||
|
.sw_iir_enable = false,
|
||
|
#endif
|
||
|
|
||
|
#if defined(__HW_DAC_IIR_EQ_PROCESS__)
|
||
|
.hw_dac_iir_enable = false,
|
||
|
#endif
|
||
|
|
||
|
#if defined(__HW_IIR_EQ_PROCESS__)
|
||
|
.hw_iir_enable = false,
|
||
|
#endif
|
||
|
|
||
|
#if defined(__HW_FIR_EQ_PROCESS__)
|
||
|
.hw_fir_enable = false,
|
||
|
#endif
|
||
|
|
||
|
#ifdef AUDIO_UPDATE_CFG
|
||
|
.update_cfg = false,
|
||
|
#endif
|
||
|
|
||
|
#ifdef AUDIO_EQ_SW_IIR_UPDATE_CFG
|
||
|
.sw_iir_cfg = {.num = 0},
|
||
|
#endif
|
||
|
|
||
|
#ifdef AUDIO_EQ_HW_DAC_IIR_UPDATE_CFG
|
||
|
.hw_dac_iir_cfg = {.num = 0},
|
||
|
#endif
|
||
|
|
||
|
#ifdef AUDIO_EQ_HW_IIR_UPDATE_CFG
|
||
|
.hw_iir_cfg = {.num = 0},
|
||
|
#endif
|
||
|
|
||
|
#ifdef AUDIO_EQ_HW_FIR_UPDATE_CFG
|
||
|
.hw_fir_cfg = {.len = 0},
|
||
|
#endif
|
||
|
|
||
|
#ifdef AUDIO_DRC_UPDATE_CFG
|
||
|
.drc_update = false,
|
||
|
.drc_cfg = {
|
||
|
.knee = 0,
|
||
|
.filter_type = {-1, -1},
|
||
|
.band_num = 1,
|
||
|
.look_ahead_time = 0,
|
||
|
.band_settings = {
|
||
|
{0, 0, 1, 1, 1, 1},
|
||
|
{0, 0, 1, 1, 1, 1},
|
||
|
}
|
||
|
},
|
||
|
#endif
|
||
|
|
||
|
#ifdef AUDIO_DRC2_UPDATE_CFG
|
||
|
.drc2_update = false,
|
||
|
.drc2_cfg = {
|
||
|
.knee = 0,
|
||
|
.look_ahead_time = 0,
|
||
|
.threshold = 0,
|
||
|
.makeup_gain = 0,
|
||
|
.ratio = 1000,
|
||
|
.attack_time = 1,
|
||
|
.release_time = 1,
|
||
|
},
|
||
|
#endif
|
||
|
};
|
||
|
|
||
|
int audio_eq_set_cfg(const FIR_CFG_T *fir_cfg, const IIR_CFG_T *iir_cfg, AUDIO_EQ_TYPE_T audio_eq_type)
|
||
|
{
|
||
|
#if defined(__SW_IIR_EQ_PROCESS__) || defined(__HW_FIR_EQ_PROCESS__)|| defined(__HW_DAC_IIR_EQ_PROCESS__)|| defined(__HW_IIR_EQ_PROCESS__)
|
||
|
switch (audio_eq_type)
|
||
|
{
|
||
|
#if defined(__SW_IIR_EQ_PROCESS__)
|
||
|
case AUDIO_EQ_TYPE_SW_IIR:
|
||
|
{
|
||
|
if(iir_cfg)
|
||
|
{
|
||
|
audio_process.sw_iir_enable = false;
|
||
|
#ifdef USB_EQ_TUNING
|
||
|
if (audio_process.eq_updated_cfg) {
|
||
|
iir_set_cfg(&audio_process.sw_iir_cfg);
|
||
|
} else
|
||
|
#endif
|
||
|
{
|
||
|
iir_set_cfg(iir_cfg);
|
||
|
}
|
||
|
audio_process.sw_iir_enable = true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
audio_process.sw_iir_enable = false;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
#endif
|
||
|
|
||
|
#if defined(__HW_FIR_EQ_PROCESS__)
|
||
|
case AUDIO_EQ_TYPE_HW_FIR:
|
||
|
{
|
||
|
if(fir_cfg)
|
||
|
{
|
||
|
audio_process.hw_fir_enable = false;
|
||
|
fir_set_cfg(fir_cfg);
|
||
|
audio_process.hw_fir_enable = true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
audio_process.hw_fir_enable = false;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
#endif
|
||
|
|
||
|
#if defined(__HW_DAC_IIR_EQ_PROCESS__)
|
||
|
case AUDIO_EQ_TYPE_HW_DAC_IIR:
|
||
|
{
|
||
|
if(iir_cfg)
|
||
|
{
|
||
|
HW_CODEC_IIR_CFG_T *hw_iir_cfg_dac=NULL;
|
||
|
enum AUD_SAMPRATE_T sample_rate_hw_dac_iir;
|
||
|
#ifdef __AUDIO_RESAMPLE__
|
||
|
int i;
|
||
|
for(i=1;i<129;i++)
|
||
|
{
|
||
|
if(audio_process.sample_rate==AUD_SAMPRATE_7350*i)break;
|
||
|
if(audio_process.sample_rate==AUD_SAMPRATE_8000*i)break;
|
||
|
}
|
||
|
TRACE(1,"audio_process.sample_rate i:%d",i);
|
||
|
if(i==129) i=6; //set default eq parameter;
|
||
|
sample_rate_hw_dac_iir=i*8463.541666f;//AUD_SAMPRATE_8463
|
||
|
#else
|
||
|
sample_rate_hw_dac_iir=audio_process.sample_rate;
|
||
|
#endif
|
||
|
audio_process.hw_dac_iir_enable = false;
|
||
|
#ifdef USB_EQ_TUNING
|
||
|
if (audio_process.eq_updated_cfg) {
|
||
|
hw_iir_cfg_dac = hw_codec_iir_get_cfg(sample_rate_hw_dac_iir, &audio_process.hw_dac_iir_cfg);
|
||
|
} else
|
||
|
#endif
|
||
|
{
|
||
|
hw_iir_cfg_dac = hw_codec_iir_get_cfg(sample_rate_hw_dac_iir,iir_cfg);
|
||
|
}
|
||
|
ASSERT(hw_iir_cfg_dac != NULL, "[%s] codec IIR parameter error!", __func__);
|
||
|
hw_codec_iir_set_cfg(hw_iir_cfg_dac, sample_rate_hw_dac_iir, HW_CODEC_IIR_DAC);
|
||
|
audio_process.hw_dac_iir_enable = true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
audio_process.hw_dac_iir_enable = false;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
#endif
|
||
|
|
||
|
#if defined(__HW_IIR_EQ_PROCESS__)
|
||
|
case AUDIO_EQ_TYPE_HW_IIR:
|
||
|
{
|
||
|
if(iir_cfg)
|
||
|
{
|
||
|
HW_IIR_CFG_T *hw_iir_cfg=NULL;
|
||
|
audio_process.hw_iir_enable = false;
|
||
|
hw_iir_cfg = hw_iir_get_cfg(audio_process.sample_rate,iir_cfg);
|
||
|
ASSERT(hw_iir_cfg != NULL,"[%s] 0x%x codec IIR parameter error!", __func__, (unsigned int)hw_iir_cfg);
|
||
|
hw_iir_set_cfg(hw_iir_cfg);
|
||
|
audio_process.hw_iir_enable = true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
audio_process.hw_iir_enable = false;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
break;
|
||
|
#endif
|
||
|
|
||
|
default:
|
||
|
{
|
||
|
ASSERT(false,"[%s]Error eq type!",__func__);
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int SRAM_TEXT_LOC audio_process_run(uint8_t *buf, uint32_t len)
|
||
|
{
|
||
|
int POSSIBLY_UNUSED pcm_len = 0;
|
||
|
|
||
|
if(audio_process.sample_bits == AUD_BITS_16)
|
||
|
{
|
||
|
pcm_len = len / sizeof(pcm_16bits_t);
|
||
|
}
|
||
|
else if(audio_process.sample_bits == AUD_BITS_24)
|
||
|
{
|
||
|
pcm_len = len / sizeof(pcm_24bits_t);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ASSERT(0, "[%s] bits(%d) is invalid", __func__, audio_process.sample_bits);
|
||
|
}
|
||
|
|
||
|
if (audio_process.sw_ch_num == audio_process.hw_ch_num) {
|
||
|
// do nothing
|
||
|
} else if (audio_process.sw_ch_num == AUD_CHANNEL_NUM_1 &&
|
||
|
audio_process.hw_ch_num == AUD_CHANNEL_NUM_2) {
|
||
|
if (audio_process.sample_bits == AUD_BITS_16) {
|
||
|
int16_t *pcm_buf = (int16_t *)buf;
|
||
|
for (uint32_t i = 0, j = 0; i < pcm_len; i += 2, j++) {
|
||
|
pcm_buf[j] = pcm_buf[i];
|
||
|
}
|
||
|
} else {
|
||
|
int32_t *pcm_buf = (int32_t *)buf;
|
||
|
for (uint32_t i = 0, j = 0; i < pcm_len; i += 2, j++) {
|
||
|
pcm_buf[j] = pcm_buf[i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pcm_len /= 2;
|
||
|
} else {
|
||
|
ASSERT(0, "[%s] sw_ch_num(%d) or hw_ch_num(%d) is invalid", __FUNCTION__, audio_process.sw_ch_num, audio_process.hw_ch_num);
|
||
|
}
|
||
|
|
||
|
#ifdef AUDIO_PROCESS_DUMP
|
||
|
int *buf32 = (int *)buf;
|
||
|
for(int i=0;i<1024;i++)
|
||
|
dump_buf[i] = buf32[2 * i]>>8;
|
||
|
audio_dump_clear_up();
|
||
|
audio_dump_add_channel_data(0, dump_buf, 1024);
|
||
|
|
||
|
#endif
|
||
|
|
||
|
//int32_t s_time,e_time;
|
||
|
//s_time = hal_fast_sys_timer_get();
|
||
|
|
||
|
#ifdef __SW_IIR_EQ_PROCESS__
|
||
|
if(audio_process.sw_iir_enable)
|
||
|
{
|
||
|
iir_run(buf, pcm_len);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#ifdef __HW_FIR_EQ_PROCESS__
|
||
|
if(audio_process.hw_fir_enable)
|
||
|
{
|
||
|
fir_run(buf, pcm_len);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#ifdef __AUDIO_DRC__
|
||
|
#ifdef AUDIO_DRC_UPDATE_CFG
|
||
|
if(audio_process.drc_update)
|
||
|
{
|
||
|
drc_set_config(audio_process.drc_st, &audio_process.drc_cfg);
|
||
|
audio_process.drc_update =false;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
drc_process(audio_process.drc_st, buf, pcm_len);
|
||
|
#endif
|
||
|
|
||
|
//int32_t m_time = hal_fast_sys_timer_get();
|
||
|
|
||
|
#ifdef __AUDIO_DRC2__
|
||
|
#ifdef AUDIO_DRC2_UPDATE_CFG
|
||
|
if(audio_process.drc2_update)
|
||
|
{
|
||
|
limiter_set_config(audio_process.drc2_st, &audio_process.drc2_cfg);
|
||
|
audio_process.drc2_update =false;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
limiter_process(audio_process.drc2_st, buf, pcm_len);
|
||
|
#endif
|
||
|
|
||
|
#ifdef __HW_IIR_EQ_PROCESS__
|
||
|
if(audio_process.hw_iir_enable)
|
||
|
{
|
||
|
hw_iir_run(buf, pcm_len);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if (audio_process.sw_ch_num == audio_process.hw_ch_num) {
|
||
|
// do nothing
|
||
|
} else if (audio_process.sw_ch_num == AUD_CHANNEL_NUM_1 &&
|
||
|
audio_process.hw_ch_num == AUD_CHANNEL_NUM_2) {
|
||
|
if (audio_process.sample_bits == AUD_BITS_16) {
|
||
|
int16_t *pcm_buf = (int16_t *)buf;
|
||
|
for (int32_t i = pcm_len - 1, j = 2 * pcm_len - 1; i >= 0; i--, j -= 2) {
|
||
|
pcm_buf[j + 1] = pcm_buf[i];
|
||
|
pcm_buf[j + 0] = pcm_buf[i];
|
||
|
}
|
||
|
} else {
|
||
|
int32_t *pcm_buf = (int32_t *)buf;
|
||
|
for (int32_t i = pcm_len - 1, j = 2 * pcm_len - 2; i >= 0; i--, j -= 2) {
|
||
|
pcm_buf[j + 1] = pcm_buf[i];
|
||
|
pcm_buf[j + 0] = pcm_buf[i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pcm_len *= 2;
|
||
|
} else {
|
||
|
ASSERT(0, "[%s] sw_ch_num(%d) or hw_ch_num(%d) is invalid", __FUNCTION__, audio_process.sw_ch_num, audio_process.hw_ch_num);
|
||
|
}
|
||
|
|
||
|
#ifdef AUDIO_PROCESS_DUMP
|
||
|
//for(int i=0;i<1024;i++)
|
||
|
// dump_buf[i] = buf32[2 * i+0]>>8;
|
||
|
//audio_dump_add_channel_data(1, dump_buf, 1024);
|
||
|
audio_dump_run();
|
||
|
#endif
|
||
|
|
||
|
//e_time = hal_fast_sys_timer_get();
|
||
|
//TRACE(4,"[%s] Sample len = %d, drc1 %d us, drc2 %d us",
|
||
|
// __func__, pcm_len, FAST_TICKS_TO_US(m_time - s_time), FAST_TICKS_TO_US(e_time - m_time));
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* frame_size stands for samples per channel
|
||
|
*/
|
||
|
int audio_process_open(enum AUD_SAMPRATE_T sample_rate, enum AUD_BITS_T sample_bits, enum AUD_CHANNEL_NUM_T sw_ch_num, enum AUD_CHANNEL_NUM_T hw_ch_num, int32_t frame_size, void *eq_buf, uint32_t len)
|
||
|
{
|
||
|
TRACE(5,"[%s] sample_rate = %d, sample_bits = %d, sw_ch_num = %d, hw_ch_num = %d", __func__, sample_rate, sample_bits, sw_ch_num, hw_ch_num);
|
||
|
#ifdef AUDIO_PROCESS_DUMP
|
||
|
audio_dump_init(1024, sizeof(short), 2);
|
||
|
#endif
|
||
|
audio_process.sample_rate = sample_rate;
|
||
|
audio_process.sample_bits = sample_bits;
|
||
|
audio_process.sw_ch_num = sw_ch_num;
|
||
|
audio_process.hw_ch_num = hw_ch_num;
|
||
|
|
||
|
#if defined(__HW_FIR_EQ_PROCESS__) && defined(__HW_IIR_EQ_PROCESS__)
|
||
|
void *fir_eq_buf = eq_buf;
|
||
|
uint32_t fir_len = len/2;
|
||
|
void *iir_eq_buf = (uint8_t *)eq_buf+fir_len;
|
||
|
uint32_t iir_len = len/2;
|
||
|
#elif defined(__HW_FIR_EQ_PROCESS__) && !defined(__HW_IIR_EQ_PROCESS__)
|
||
|
void *fir_eq_buf = eq_buf;
|
||
|
uint32_t fir_len = len;
|
||
|
#elif !defined(__HW_FIR_EQ_PROCESS__) && defined(__HW_IIR_EQ_PROCESS__)
|
||
|
void *iir_eq_buf = eq_buf;
|
||
|
uint32_t iir_len = len;
|
||
|
#endif
|
||
|
|
||
|
#ifdef __SW_IIR_EQ_PROCESS__
|
||
|
iir_open(sample_rate, sample_bits,sw_ch_num);
|
||
|
#ifdef AUDIO_EQ_SW_IIR_UPDATE_CFG
|
||
|
audio_eq_set_cfg(NULL, &audio_process.sw_iir_cfg, AUDIO_EQ_TYPE_SW_IIR);
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
#ifdef __HW_DAC_IIR_EQ_PROCESS__
|
||
|
enum AUD_SAMPRATE_T sample_rate_hw_dac_iir;
|
||
|
#ifdef __AUDIO_RESAMPLE__
|
||
|
int i;
|
||
|
for(i=1;i<129;i++)
|
||
|
{
|
||
|
if(audio_process.sample_rate==AUD_SAMPRATE_7350*i)break;
|
||
|
if(audio_process.sample_rate==AUD_SAMPRATE_8000*i)break;
|
||
|
}
|
||
|
TRACE(1,"sample_rate i:%d",i);
|
||
|
if(i==129) i=6; //set default eq parameter;
|
||
|
sample_rate_hw_dac_iir=i*8463.541666f;//AUD_SAMPRATE_8463
|
||
|
#else
|
||
|
sample_rate_hw_dac_iir = audio_process.sample_rate;
|
||
|
#endif
|
||
|
|
||
|
hw_codec_iir_open(sample_rate_hw_dac_iir, HW_CODEC_IIR_DAC, CODEC_OUTPUT_DEV);
|
||
|
#ifdef AUDIO_EQ_HW_DAC_IIR_UPDATE_CFG
|
||
|
audio_eq_set_cfg(NULL, &audio_process.hw_dac_iir_cfg, AUDIO_EQ_TYPE_HW_DAC_IIR);
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
#ifdef __HW_IIR_EQ_PROCESS__
|
||
|
hw_iir_open(sample_rate, sample_bits, sw_ch_num, iir_eq_buf, iir_len);
|
||
|
#ifdef AUDIO_EQ_HW_IIR_UPDATE_CFG
|
||
|
audio_eq_set_cfg(NULL, &audio_process.hw_iir_cfg, AUDIO_EQ_TYPE_HW_IIR);
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
#ifdef __HW_FIR_EQ_PROCESS__
|
||
|
#if defined(CHIP_BEST1000) && defined(FIR_HIGHSPEED)
|
||
|
hal_cmu_fir_high_speed_enable(HAL_CMU_FIR_USER_EQ);
|
||
|
#endif
|
||
|
fir_open(sample_rate, sample_bits, sw_ch_num, fir_eq_buf, fir_len);
|
||
|
#ifdef AUDIO_EQ_HW_FIR_UPDATE_CFG
|
||
|
audio_eq_set_cfg(&audio_process.hw_fir_cfg, NULL, AUDIO_EQ_TYPE_HW_FIR);
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
#if AUDIO_MEMORY_SIZE > 0
|
||
|
syspool_get_buff(&audio_process.audio_heap, AUDIO_MEMORY_SIZE);
|
||
|
audio_heap_init(audio_process.audio_heap, AUDIO_MEMORY_SIZE);
|
||
|
#endif
|
||
|
|
||
|
#ifdef __AUDIO_DRC__
|
||
|
audio_process.drc_st = drc_create(sample_rate, frame_size, sample_bits, sw_ch_num,
|
||
|
#ifdef AUDIO_DRC_UPDATE_CFG
|
||
|
&audio_process.drc_cfg
|
||
|
#else
|
||
|
&audio_drc_cfg
|
||
|
#endif
|
||
|
);
|
||
|
#ifdef AUDIO_DRC_UPDATE_CFG
|
||
|
audio_process.drc_update = false;
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
#ifdef __AUDIO_DRC2__
|
||
|
audio_process.drc2_st = limiter_create(sample_rate, frame_size, sample_bits, sw_ch_num,
|
||
|
#ifdef AUDIO_DRC2_UPDATE_CFG
|
||
|
&audio_process.drc2_cfg
|
||
|
#else
|
||
|
&audio_drc2_cfg
|
||
|
#endif
|
||
|
);
|
||
|
#ifdef AUDIO_DRC2_UPDATE_CFG
|
||
|
audio_process.drc2_update = false;
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
#if defined(__PC_CMD_UART__) && defined(USB_AUDIO_APP)
|
||
|
hal_cmd_open();
|
||
|
#endif
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int audio_process_close(void)
|
||
|
{
|
||
|
#ifdef __SW_IIR_EQ_PROCESS__
|
||
|
audio_process.sw_iir_enable = false;
|
||
|
iir_close();
|
||
|
#endif
|
||
|
|
||
|
#ifdef __HW_DAC_IIR_EQ_PROCESS__
|
||
|
audio_process.hw_dac_iir_enable = false;
|
||
|
hw_codec_iir_close(HW_CODEC_IIR_DAC);
|
||
|
#endif
|
||
|
|
||
|
#ifdef __HW_IIR_EQ_PROCESS__
|
||
|
audio_process.hw_iir_enable = false;
|
||
|
hw_iir_close();
|
||
|
#endif
|
||
|
|
||
|
#ifdef __HW_FIR_EQ_PROCESS__
|
||
|
audio_process.hw_fir_enable = false;
|
||
|
fir_close();
|
||
|
#if defined(CHIP_BEST1000) && defined(FIR_HIGHSPEED)
|
||
|
hal_cmu_fir_high_speed_disable(HAL_CMU_FIR_USER_EQ);
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
#ifdef __AUDIO_DRC__
|
||
|
#ifdef AUDIO_DRC_UPDATE_CFG
|
||
|
audio_process.drc_update = false;
|
||
|
#endif
|
||
|
drc_destroy(audio_process.drc_st);
|
||
|
audio_process.drc_st = NULL;
|
||
|
#endif
|
||
|
|
||
|
#ifdef __AUDIO_DRC2__
|
||
|
#ifdef AUDIO_DRC2_UPDATE_CFG
|
||
|
audio_process.drc2_update = false;
|
||
|
#endif
|
||
|
limiter_destroy(audio_process.drc2_st);
|
||
|
audio_process.drc2_st = NULL;
|
||
|
#endif
|
||
|
|
||
|
#if AUDIO_MEMORY_SIZE > 0
|
||
|
size_t total = 0, used = 0, max_used = 0;
|
||
|
audio_memory_info(&total, &used, &max_used);
|
||
|
TRACE(3,"AUDIO MALLOC MEM: total - %d, used - %d, max_used - %d.", total, used, max_used);
|
||
|
ASSERT(used == 0, "[%s] used != 0", __func__);
|
||
|
#endif
|
||
|
|
||
|
#if defined(__PC_CMD_UART__) && defined(USB_AUDIO_APP)
|
||
|
hal_cmd_close();
|
||
|
#endif
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
#if defined(__PC_CMD_UART__) || defined(USB_EQ_TUNING)
|
||
|
int audio_ping_callback(uint8_t *buf, uint32_t len)
|
||
|
{
|
||
|
//TRACE(0,"");
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
#if defined(AUDIO_EQ_SW_IIR_UPDATE_CFG) && !defined(USB_EQ_TUNING)
|
||
|
#ifndef USB_AUDIO_APP
|
||
|
int audio_eq_sw_iir_callback(uint8_t *buf, uint32_t len)
|
||
|
{
|
||
|
TRACE(3,"[%s] len = %d, sizeof(struct) = %d", __func__, len, sizeof(IIR_CFG_T));
|
||
|
|
||
|
if (len != sizeof(IIR_CFG_T))
|
||
|
{
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
memcpy(&audio_process.sw_iir_cfg, buf, sizeof(IIR_CFG_T));
|
||
|
TRACE(3,"band num:%d gain0:%d, gain1:%d",
|
||
|
(int32_t)audio_process.sw_iir_cfg.num,
|
||
|
(int32_t)(audio_process.sw_iir_cfg.gain0*10),
|
||
|
(int32_t)(audio_process.sw_iir_cfg.gain1*10));
|
||
|
for (uint8_t i = 0; i<audio_process.sw_iir_cfg.num; i++){
|
||
|
TRACE(5,"band num:%d type %d gain:%d fc:%d q:%d", i,
|
||
|
(int32_t)(audio_process.sw_iir_cfg.param[i].type),
|
||
|
(int32_t)(audio_process.sw_iir_cfg.param[i].gain*10),
|
||
|
(int32_t)(audio_process.sw_iir_cfg.param[i].fc*10),
|
||
|
(int32_t)(audio_process.sw_iir_cfg.param[i].Q*10));
|
||
|
}
|
||
|
|
||
|
#ifdef __SW_IIR_EQ_PROCESS__
|
||
|
{
|
||
|
iir_set_cfg(&audio_process.sw_iir_cfg);
|
||
|
audio_process.sw_iir_enable = true;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
#else
|
||
|
int audio_eq_sw_iir_callback(uint8_t *buf, uint32_t len)
|
||
|
{
|
||
|
// IIR_CFG_T *rx_iir_cfg = NULL;
|
||
|
|
||
|
// rx_iir_cfg = (IIR_CFG_T *)buf;
|
||
|
|
||
|
// TRACE(3,"[%s] left gain = %f, right gain = %f", __func__, rx_iir_cfg->gain0, rx_iir_cfg->gain1);
|
||
|
|
||
|
// for(int i=0; i<rx_iir_cfg->num; i++)
|
||
|
// {
|
||
|
// TRACE(5,"[%s] iir[%d] gain = %f, f = %f, Q = %f", __func__, i, rx_iir_cfg->param[i].gain, rx_iir_cfg->param[i].fc, rx_iir_cfg->param[i].Q);
|
||
|
// }
|
||
|
|
||
|
// audio_eq_set_cfg(NULL,(const IIR_CFG_T *)rx_iir_cfg,AUDIO_EQ_TYPE_SW_IIR);
|
||
|
|
||
|
iir_update_cfg_tbl(buf, len);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
#ifdef AUDIO_EQ_HW_FIR_UPDATE_CFG
|
||
|
int audio_eq_hw_fir_callback(uint8_t *buf, uint32_t len)
|
||
|
{
|
||
|
TRACE(3,"[%s] len = %d, sizeof(struct) = %d", __func__, len, sizeof(FIR_CFG_T));
|
||
|
|
||
|
if (len != sizeof(FIR_CFG_T))
|
||
|
{
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
FIR_CFG_T *rx_fir_cfg = NULL;
|
||
|
|
||
|
rx_fir_cfg = (FIR_CFG_T *)buf;
|
||
|
|
||
|
TRACE(3,"[%s] left gain = %d, right gain = %d", __func__, rx_fir_cfg->gain0, rx_fir_cfg->gain1);
|
||
|
|
||
|
TRACE(6,"[%s] len = %d, coef: %d, %d......%d, %d", __func__, rx_fir_cfg->len, rx_fir_cfg->coef[0], rx_fir_cfg->coef[1], rx_fir_cfg->coef[rx_fir_cfg->len-2], rx_fir_cfg->coef[rx_fir_cfg->len-1]);
|
||
|
|
||
|
rx_fir_cfg->gain0 = 6;
|
||
|
rx_fir_cfg->gain1 = 6;
|
||
|
|
||
|
if(rx_fir_cfg)
|
||
|
{
|
||
|
memcpy(&audio_process.fir_cfg, rx_fir_cfg, sizeof(audio_process.fir_cfg));
|
||
|
audio_process.fir_enable = true;
|
||
|
fir_set_cfg(&audio_process.fir_cfg);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
audio_process.fir_enable = false;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#ifdef AUDIO_DRC_UPDATE_CFG
|
||
|
int audio_drc_callback(uint8_t *buf, uint32_t len)
|
||
|
{
|
||
|
TRACE(3,"[%s] len = %d, sizeof(struct) = %d", __func__, len, sizeof(DrcConfig));
|
||
|
|
||
|
if (len != sizeof(DrcConfig))
|
||
|
{
|
||
|
TRACE(1,"[%s] WARNING: Length is different", __func__);
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
if (audio_process.drc_st == NULL)
|
||
|
{
|
||
|
TRACE(1,"[%s] WARNING: audio_process.drc2_st = NULL", __func__);
|
||
|
TRACE(1,"[%s] WARNING: Please Play music, then tuning Limiter", __func__);
|
||
|
|
||
|
return 2;
|
||
|
}
|
||
|
|
||
|
memcpy(&audio_process.drc_cfg, buf, sizeof(DrcConfig));
|
||
|
audio_process.drc_update = true;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#ifdef AUDIO_DRC2_UPDATE_CFG
|
||
|
int audio_drc2_callback(uint8_t *buf, uint32_t len)
|
||
|
{
|
||
|
TRACE(3,"[%s] len = %d, sizeof(struct) = %d", __func__, len, sizeof(LimiterConfig));
|
||
|
|
||
|
if (len != sizeof(LimiterConfig))
|
||
|
{
|
||
|
TRACE(1,"[%s] WARNING: Length is different", __func__);
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
if (audio_process.drc2_st == NULL)
|
||
|
{
|
||
|
TRACE(1,"[%s] WARNING: audio_process.drc2_st = NULL", __func__);
|
||
|
TRACE(1,"[%s] WARNING: Please Play music, then tuning Limiter", __func__);
|
||
|
|
||
|
return 2;
|
||
|
}
|
||
|
|
||
|
memcpy(&audio_process.drc2_cfg, buf, sizeof(LimiterConfig));
|
||
|
audio_process.drc2_update = true;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if defined(AUDIO_EQ_HW_DAC_IIR_UPDATE_CFG) && !defined(USB_EQ_TUNING)
|
||
|
int audio_eq_hw_dac_iir_callback(uint8_t *buf, uint32_t len)
|
||
|
{
|
||
|
TRACE(3,"[%s] len = %d, sizeof(struct) = %d", __func__, len, sizeof(IIR_CFG_T));
|
||
|
|
||
|
if (len != sizeof(IIR_CFG_T))
|
||
|
{
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
memcpy(&audio_process.hw_dac_iir_cfg, buf, sizeof(IIR_CFG_T));
|
||
|
TRACE(3,"band num:%d gain0:%d, gain1:%d",
|
||
|
(int32_t)audio_process.hw_dac_iir_cfg.num,
|
||
|
(int32_t)(audio_process.hw_dac_iir_cfg.gain0*10),
|
||
|
(int32_t)(audio_process.hw_dac_iir_cfg.gain1*10));
|
||
|
for (uint8_t i = 0; i<audio_process.hw_dac_iir_cfg.num; i++){
|
||
|
TRACE(5,"band num:%d type %d gain:%d fc:%d q:%d", i,
|
||
|
(int32_t)(audio_process.hw_dac_iir_cfg.param[i].type),
|
||
|
(int32_t)(audio_process.hw_dac_iir_cfg.param[i].gain*10),
|
||
|
(int32_t)(audio_process.hw_dac_iir_cfg.param[i].fc*10),
|
||
|
(int32_t)(audio_process.hw_dac_iir_cfg.param[i].Q*10));
|
||
|
}
|
||
|
|
||
|
#ifdef __HW_DAC_IIR_EQ_PROCESS__
|
||
|
{
|
||
|
HW_CODEC_IIR_CFG_T *hw_iir_cfg_dac = NULL;
|
||
|
enum AUD_SAMPRATE_T sample_rate_hw_dac_iir;
|
||
|
#ifdef __AUDIO_RESAMPLE__
|
||
|
int i;
|
||
|
for(i=1;i<129;i++)
|
||
|
{
|
||
|
if(audio_process.sample_rate==AUD_SAMPRATE_7350*i)break;
|
||
|
if(audio_process.sample_rate==AUD_SAMPRATE_8000*i)break;
|
||
|
}
|
||
|
TRACE(1,"audio_process.sample_rate i:%d",i);
|
||
|
if(i==129) i=6; //set default eq parameter;
|
||
|
sample_rate_hw_dac_iir=i*8463.541666f;//AUD_SAMPRATE_8463
|
||
|
#else
|
||
|
sample_rate_hw_dac_iir = audio_process.sample_rate;
|
||
|
#endif
|
||
|
hw_iir_cfg_dac = hw_codec_iir_get_cfg(sample_rate_hw_dac_iir,&audio_process.hw_dac_iir_cfg);
|
||
|
ASSERT(hw_iir_cfg_dac != NULL, "[%s] %d codec IIR parameter error!", __func__, (uint32_t)hw_iir_cfg_dac);
|
||
|
|
||
|
// hal_codec_iir_dump(hw_iir_cfg_dac);
|
||
|
|
||
|
hw_codec_iir_set_cfg(hw_iir_cfg_dac, sample_rate_hw_dac_iir, HW_CODEC_IIR_DAC);
|
||
|
audio_process.hw_dac_iir_enable = true;
|
||
|
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
#ifdef AUDIO_EQ_HW_IIR_UPDATE_CFG
|
||
|
int audio_eq_hw_iir_callback(uint8_t *buf, uint32_t len)
|
||
|
{
|
||
|
TRACE(3,"[%s] len = %d, sizeof(struct) = %d", __func__, len, sizeof(IIR_CFG_T));
|
||
|
|
||
|
if (len != sizeof(IIR_CFG_T))
|
||
|
{
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
memcpy(&audio_process.hw_iir_cfg, buf, sizeof(IIR_CFG_T));
|
||
|
TRACE(3,"band num:%d gain0:%d, gain1:%d",
|
||
|
(int32_t)audio_process.hw_iir_cfg.num,
|
||
|
(int32_t)(audio_process.hw_iir_cfg.gain0*10),
|
||
|
(int32_t)(audio_process.hw_iir_cfg.gain1*10));
|
||
|
|
||
|
for (uint8_t i = 0; i<audio_process.hw_iir_cfg.num; i++)
|
||
|
{
|
||
|
TRACE(5,"band num:%d type %d gain:%d fc:%d q:%d", i,
|
||
|
(int32_t)(audio_process.hw_iir_cfg.param[i].type),
|
||
|
(int32_t)(audio_process.hw_iir_cfg.param[i].gain*10),
|
||
|
(int32_t)(audio_process.hw_iir_cfg.param[i].fc*10),
|
||
|
(int32_t)(audio_process.hw_iir_cfg.param[i].Q*10));
|
||
|
}
|
||
|
|
||
|
#ifdef __HW_IIR_EQ_PROCESS__
|
||
|
{
|
||
|
HW_IIR_CFG_T *hw_iir_cfg=NULL;
|
||
|
#ifdef __AUDIO_RESAMPLE__
|
||
|
enum AUD_SAMPRATE_T sample_rate_hw_iir=AUD_SAMPRATE_50781;
|
||
|
#else
|
||
|
enum AUD_SAMPRATE_T sample_rate_hw_iir=audio_process.sample_rate;
|
||
|
#endif
|
||
|
hw_iir_cfg = hw_iir_get_cfg(sample_rate_hw_iir,&audio_process.hw_iir_cfg);
|
||
|
ASSERT(hw_iir_cfg != NULL, "[%s] %d codec IIR parameter error!", __func__, hw_iir_cfg);
|
||
|
hw_iir_set_cfg(hw_iir_cfg);
|
||
|
audio_process.hw_iir_enable = true;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
#endif // #ifdef __PC_CMD_UART__
|
||
|
|
||
|
#ifdef USB_EQ_TUNING
|
||
|
|
||
|
int audio_eq_usb_iir_callback(uint8_t *buf, uint32_t len)
|
||
|
{
|
||
|
IIR_CFG_T* cur_cfg;
|
||
|
|
||
|
TRACE(2,"usb_iir_cb: len=[%d - %d]", len, sizeof(IIR_CFG_T));
|
||
|
|
||
|
if (len != sizeof(IIR_CFG_T)) {
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
cur_cfg = (IIR_CFG_T*)buf;
|
||
|
TRACE(2,"-> sample_rate[%d], num[%d]", /*cur_cfg->samplerate,*/ audio_process.sample_rate, cur_cfg->num);
|
||
|
|
||
|
#if defined(AUDIO_EQ_SW_IIR_UPDATE_CFG)
|
||
|
audio_process.sw_iir_cfg.gain0 = cur_cfg->gain0;
|
||
|
audio_process.sw_iir_cfg.gain1 = cur_cfg->gain1;
|
||
|
#endif
|
||
|
|
||
|
#if defined(AUDIO_EQ_HW_DAC_IIR_UPDATE_CFG)
|
||
|
#if defined(AUDIO_EQ_SW_IIR_UPDATE_CFG)
|
||
|
audio_process.hw_dac_iir_cfg.gain0 = 0;
|
||
|
audio_process.hw_dac_iir_cfg.gain1 = 0;
|
||
|
#else
|
||
|
audio_process.hw_dac_iir_cfg.gain0 = cur_cfg->gain0;
|
||
|
audio_process.hw_dac_iir_cfg.gain1 = cur_cfg->gain1;
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
#if defined(AUDIO_EQ_HW_DAC_IIR_UPDATE_CFG)
|
||
|
if (cur_cfg->num > AUD_DAC_IIR_NUM_EQ) {
|
||
|
audio_process.hw_dac_iir_cfg.num = AUD_DAC_IIR_NUM_EQ;
|
||
|
} else {
|
||
|
audio_process.hw_dac_iir_cfg.num = cur_cfg->num;
|
||
|
}
|
||
|
TRACE(1,"-> hw_dac_iir_num[%d]", audio_process.hw_dac_iir_cfg.num);
|
||
|
#endif
|
||
|
|
||
|
#if defined(AUDIO_EQ_SW_IIR_UPDATE_CFG)
|
||
|
audio_process.sw_iir_cfg.num = cur_cfg->num - audio_process.hw_dac_iir_cfg.num;
|
||
|
TRACE(1,"-> sw_iir_num[%d]", audio_process.sw_iir_cfg.num);
|
||
|
#endif
|
||
|
//TRACE(2,"-> iir_num[%d - %d]", audio_process.hw_dac_iir_cfg.num, audio_process.sw_iir_cfg.num);
|
||
|
|
||
|
#if defined(AUDIO_EQ_HW_DAC_IIR_UPDATE_CFG)
|
||
|
if (audio_process.hw_dac_iir_cfg.num) {
|
||
|
memcpy((void*)(&audio_process.hw_dac_iir_cfg.param[0]),
|
||
|
(void*)(&cur_cfg->param[0]),
|
||
|
audio_process.hw_dac_iir_cfg.num*sizeof(IIR_PARAM_T));
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if defined(AUDIO_EQ_SW_IIR_UPDATE_CFG)
|
||
|
if (audio_process.sw_iir_cfg.num) {
|
||
|
|
||
|
memcpy((void*)(&audio_process.sw_iir_cfg.param[0]),
|
||
|
(void*)(&cur_cfg->param[audio_process.hw_dac_iir_cfg.num]),
|
||
|
audio_process.sw_iir_cfg.num * sizeof(IIR_PARAM_T));
|
||
|
|
||
|
} else {
|
||
|
|
||
|
// set a default filter
|
||
|
audio_process.sw_iir_cfg.num = 1;
|
||
|
|
||
|
audio_process.sw_iir_cfg.param[0].fc = 1000.0;
|
||
|
audio_process.sw_iir_cfg.param[0].gain = 0.0;
|
||
|
audio_process.sw_iir_cfg.param[0].type = IIR_TYPE_PEAK;
|
||
|
audio_process.sw_iir_cfg.param[0].Q = 1.0;
|
||
|
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if (audio_process.sample_rate) {
|
||
|
audio_process.update_cfg = true;
|
||
|
}
|
||
|
|
||
|
audio_process.eq_updated_cfg = true;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void audio_eq_usb_eq_update (void)
|
||
|
{
|
||
|
if (audio_process.update_cfg) {
|
||
|
|
||
|
#if defined(AUDIO_EQ_HW_DAC_IIR_UPDATE_CFG)
|
||
|
HW_CODEC_IIR_CFG_T *hw_iir_cfg_dac = NULL;
|
||
|
|
||
|
if (audio_process.hw_dac_iir_cfg.num) {
|
||
|
enum AUD_SAMPRATE_T sample_rate_hw_dac_iir;
|
||
|
#ifdef __AUDIO_RESAMPLE__
|
||
|
int i;
|
||
|
for(i=1;i<129;i++)
|
||
|
{
|
||
|
if(audio_process.sample_rate==AUD_SAMPRATE_7350*i)break;
|
||
|
if(audio_process.sample_rate==AUD_SAMPRATE_8000*i)break;
|
||
|
}
|
||
|
TRACE(1,"audio_process.sample_rate i:%d",i);
|
||
|
if(i==129) i=6; //set default eq parameter;
|
||
|
sample_rate_hw_dac_iir=i*8463.541666f;//AUD_SAMPRATE_8463
|
||
|
#else
|
||
|
sample_rate_hw_dac_iir = audio_process.sample_rate;
|
||
|
#endif
|
||
|
hw_iir_cfg_dac = hw_codec_iir_get_cfg(sample_rate_hw_dac_iir, &audio_process.hw_dac_iir_cfg);
|
||
|
|
||
|
hw_codec_iir_set_cfg(hw_iir_cfg_dac, sample_rate_hw_dac_iir, HW_CODEC_IIR_DAC);
|
||
|
audio_process.hw_dac_iir_enable = true;
|
||
|
|
||
|
} else {
|
||
|
|
||
|
audio_process.hw_dac_iir_enable = false;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if defined(AUDIO_EQ_SW_IIR_UPDATE_CFG)
|
||
|
iir_set_cfg(&audio_process.sw_iir_cfg);
|
||
|
audio_process.sw_iir_enable = true;
|
||
|
#endif
|
||
|
|
||
|
audio_process.update_cfg = false;
|
||
|
|
||
|
/*
|
||
|
TRACE(4,"USB EQ Update: en[%d-%d], num[%d-%d]",
|
||
|
audio_process.hw_dac_iir_enable, audio_process.sw_iir_enable,
|
||
|
audio_process.hw_dac_iir_cfg.num, audio_process.sw_iir_cfg.num);
|
||
|
*/
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
#endif // USB_EQ_TUNING
|
||
|
|
||
|
|
||
|
typedef struct {
|
||
|
uint8_t type;
|
||
|
uint8_t maxEqBandNum;
|
||
|
uint16_t sample_rate_num;
|
||
|
uint8_t sample_rate[50];
|
||
|
} query_eq_info_t;
|
||
|
|
||
|
|
||
|
extern int getMaxEqBand(void);
|
||
|
extern int getSampleArray(uint8_t* buf, uint16_t *num);
|
||
|
|
||
|
extern void hal_cmd_set_res_playload(uint8_t* data, int len);
|
||
|
#define CMD_TYPE_QUERY_DUT_EQ_INFO 0x00
|
||
|
int audio_cmd_callback(uint8_t *buf, uint32_t len)
|
||
|
{
|
||
|
uint8_t type;
|
||
|
//uint32_t* sample_rate;
|
||
|
//uint8_t* p;
|
||
|
query_eq_info_t info;
|
||
|
|
||
|
type = buf[0];
|
||
|
//p = buf + 1;
|
||
|
|
||
|
TRACE(2,"%s type: %d", __func__, type);
|
||
|
switch (type) {
|
||
|
case CMD_TYPE_QUERY_DUT_EQ_INFO:
|
||
|
info.type = CMD_TYPE_QUERY_DUT_EQ_INFO;
|
||
|
info.maxEqBandNum = getMaxEqBand();
|
||
|
getSampleArray(info.sample_rate, &info.sample_rate_num);
|
||
|
|
||
|
hal_cmd_set_res_playload((uint8_t*)&info, 4 + info.sample_rate_num * 4);
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
#ifdef AUDIO_SECTION_ENABLE
|
||
|
int audio_cfg_burn_callback(uint8_t *buf, uint32_t len)
|
||
|
{
|
||
|
TRACE(3,"[%s] len = %d, sizeof(struct) = %d", __func__, len, sizeof_audio_cfg());
|
||
|
|
||
|
if (len != sizeof_audio_cfg())
|
||
|
{
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int res = 0;
|
||
|
res = store_audio_cfg_into_audio_section((AUDIO_CFG_T *)buf);
|
||
|
|
||
|
if(res)
|
||
|
{
|
||
|
TRACE(2,"[%s] ERROR: res = %d", __func__, res);
|
||
|
res += 100;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
TRACE(1,"[%s] Store audio cfg into audio section!!!", __func__);
|
||
|
}
|
||
|
|
||
|
return res;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
int audio_process_init(void)
|
||
|
{
|
||
|
#ifdef __PC_CMD_UART__
|
||
|
hal_cmd_init();
|
||
|
|
||
|
#ifdef AUDIO_EQ_SW_IIR_UPDATE_CFG
|
||
|
hal_cmd_register("iir_eq", audio_eq_sw_iir_callback); // Will be removed
|
||
|
hal_cmd_register("sw_iir_eq", audio_eq_sw_iir_callback);
|
||
|
#endif
|
||
|
|
||
|
#ifdef AUDIO_EQ_HW_DAC_IIR_UPDATE_CFG
|
||
|
hal_cmd_register("iir_eq", audio_eq_hw_dac_iir_callback); // Will be removed
|
||
|
hal_cmd_register("dac_iir_eq", audio_eq_hw_dac_iir_callback);
|
||
|
#endif
|
||
|
|
||
|
#ifdef AUDIO_EQ_HW_IIR_UPDATE_CFG
|
||
|
hal_cmd_register("iir_eq", audio_eq_hw_iir_callback); // Will be removed
|
||
|
hal_cmd_register("hw_iir_eq", audio_eq_hw_iir_callback);
|
||
|
#endif
|
||
|
|
||
|
#ifdef AUDIO_EQ_HW_FIR_UPDATE_CFG
|
||
|
hal_cmd_register("fir_eq", audio_eq_hw_fir_callback);
|
||
|
#endif
|
||
|
|
||
|
#ifdef AUDIO_DRC_UPDATE_CFG
|
||
|
hal_cmd_register("drc", audio_drc_callback);
|
||
|
#endif
|
||
|
|
||
|
#ifdef AUDIO_DRC2_UPDATE_CFG
|
||
|
hal_cmd_register("limiter", audio_drc2_callback);
|
||
|
#endif
|
||
|
|
||
|
#ifdef AUDIO_SECTION_ENABLE
|
||
|
hal_cmd_register("burn", audio_cfg_burn_callback);
|
||
|
hal_cmd_register("audio_burn", audio_cfg_burn_callback);
|
||
|
#endif
|
||
|
|
||
|
hal_cmd_register("cmd", audio_cmd_callback);
|
||
|
hal_cmd_register("ping", audio_ping_callback);
|
||
|
#endif
|
||
|
|
||
|
#ifdef USB_EQ_TUNING
|
||
|
|
||
|
hal_cmd_init();
|
||
|
|
||
|
#if defined(AUDIO_EQ_SW_IIR_UPDATE_CFG) || defined(AUDIO_EQ_HW_DAC_IIR_UPDATE_CFG)
|
||
|
hal_cmd_register("iir_eq", audio_eq_usb_iir_callback);
|
||
|
#endif
|
||
|
|
||
|
hal_cmd_register("cmd", audio_cmd_callback);
|
||
|
hal_cmd_register("ping", audio_ping_callback);
|
||
|
|
||
|
#endif
|
||
|
|
||
|
// load default cfg
|
||
|
#ifdef AUDIO_EQ_SW_IIR_UPDATE_CFG
|
||
|
memcpy(&audio_process.sw_iir_cfg, audio_eq_sw_iir_cfg_list[0], sizeof(IIR_CFG_T));
|
||
|
#endif
|
||
|
|
||
|
#ifdef AUDIO_EQ_HW_DAC_IIR_UPDATE_CFG
|
||
|
memcpy(&audio_process.hw_dac_iir_cfg, audio_eq_hw_dac_iir_cfg_list[0], sizeof(IIR_CFG_T));
|
||
|
#endif
|
||
|
|
||
|
#ifdef AUDIO_EQ_HW_IIR_UPDATE_CFG
|
||
|
memcpy(&audio_process.hw_iir_cfg, audio_eq_hw_iir_cfg_list[0], sizeof(IIR_CFG_T));
|
||
|
#endif
|
||
|
|
||
|
#ifdef AUDIO_EQ_HW_FIR_UPDATE_CFG
|
||
|
memcpy(&audio_process.hw_fir_cfg, audio_eq_hw_fir_cfg_list[0], sizeof(FIR_CFG_T));
|
||
|
#endif
|
||
|
|
||
|
#ifdef AUDIO_DRC_UPDATE_CFG
|
||
|
memcpy(&audio_process.drc_cfg, &audio_drc_cfg, sizeof(DrcConfig));
|
||
|
#endif
|
||
|
|
||
|
#ifdef AUDIO_DRC2_UPDATE_CFG
|
||
|
memcpy(&audio_process.drc2_cfg, &audio_drc2_cfg, sizeof(LimiterConfig));
|
||
|
#endif
|
||
|
|
||
|
return 0;
|
||
|
}
|