|  | /* | 
|  | *  Copyright (C) 2017 Sanechips Technology Co., Ltd. | 
|  | * | 
|  | * | 
|  | *  Use of this source code is governed by a BSD-style license | 
|  | *  that can be found in the LICENSE file in the root of the source | 
|  | *  tree. An additional intellectual property rights grant can be found | 
|  | *  in the file PATENTS.  All contributing project authors may | 
|  | *  be found in the AUTHORS file in the root of the source tree. | 
|  | */ | 
|  |  | 
|  |  | 
|  |  | 
|  | /**************************************************************************** | 
|  | * 	                                           Include files | 
|  | ****************************************************************************/ | 
|  | #include <stdio.h> | 
|  | #include <unistd.h> | 
|  | #include <string.h> | 
|  | #include <fcntl.h> | 
|  | #include <stdint.h> | 
|  | #include <stdbool.h> | 
|  | #include <errno.h> | 
|  | #include <stdlib.h> | 
|  | #include <ctype.h> | 
|  | #include <math.h> | 
|  | /**************************************************************************** | 
|  | * 	                                           Local Macros | 
|  | ****************************************************************************/ | 
|  | #define DB_COFF_ARRAY_SIZE 15 | 
|  | #define DRV_SUCCESS 0 | 
|  | #define DRV_ERROR -1 | 
|  |  | 
|  | typedef signed char SINT8; | 
|  | typedef unsigned char UINT8; | 
|  | typedef short SINT16; | 
|  | typedef unsigned short UINT16; | 
|  | typedef long SINT32; | 
|  | typedef void VOID; | 
|  | /**************************************************************************** | 
|  | * 	                                          Global Constants | 
|  | ****************************************************************************/ | 
|  |  | 
|  |  | 
|  | /**************************************************************************** | 
|  | * 	                                          Global Variables | 
|  | ****************************************************************************/ | 
|  |  | 
|  |  | 
|  | typedef enum { | 
|  | VOL_PATH_RX = 0, | 
|  | VOL_PATH_TX = 1, | 
|  | MAX_VOL_PATH = VOL_PATH_TX | 
|  | } T_Vol_Path; | 
|  |  | 
|  | typedef struct { | 
|  |  | 
|  | float gain; | 
|  | float coff; | 
|  |  | 
|  | } T_Db_Coff; | 
|  |  | 
|  | typedef struct { | 
|  |  | 
|  | int  rx_vol;	//0~5 | 
|  | float  rx_coff; | 
|  | int  rx_upflag;	//rx vol update flag , 1 update, else not | 
|  |  | 
|  | int  tx_vol;	//0~5 | 
|  | float  tx_coff; | 
|  | int  tx_upflag;	//tx vol update flag , 1 update, else not | 
|  |  | 
|  | } T_Vol_Inst; | 
|  |  | 
|  | typedef struct { | 
|  | int vol_on;// 0 off, 1 on | 
|  | float vol[6]; | 
|  | } T_Wrtc_Vol_Para; | 
|  |  | 
|  | T_Wrtc_Vol_Para vol_para = { | 
|  | 1, | 
|  | // tx_vol vol[6]; | 
|  | { | 
|  | -6,//vol0 | 
|  | -3,//vol1 | 
|  | 0,//vol2 | 
|  | 3,//vol3 | 
|  | 6,//vol4 | 
|  | 9,//vol5 | 
|  | }, | 
|  | }; | 
|  |  | 
|  | #if 1 | 
|  | T_Db_Coff coff_table[] = { | 
|  | {-96.000000,0.000016}, | 
|  | {-15.000000,0.177828}, | 
|  | {-14.000000,0.199526}, | 
|  | {-13.000000,0.223872}, | 
|  | {-12.000000,0.251189}, | 
|  | {-11.000000,0.281838}, | 
|  | {-10.000000,0.316228}, | 
|  | {-9.000000,0.354813}, | 
|  | {-8.000000,0.398107}, | 
|  | {-7.000000,0.446684}, | 
|  | {-6.000000,0.501187}, | 
|  | {-5.000000,0.562341}, | 
|  | {-4.000000,0.630957}, | 
|  | {-3.000000,0.707946}, | 
|  | {-2.000000,0.794328}, | 
|  | {-1.000000,0.891251}, | 
|  | {0.000000,1.000000}, | 
|  | {1.000000,1.122018}, | 
|  | {2.000000,1.258925}, | 
|  | {3.000000,1.412538}, | 
|  | {4.000000,1.584893}, | 
|  | {5.000000,1.778279}, | 
|  | {6.000000,1.995262}, | 
|  | {7.000000,2.238721}, | 
|  | {8.000000,2.511886}, | 
|  | {9.000000,2.818383}, | 
|  | {10.000000,3.162278}, | 
|  | {11.000000,3.548134}, | 
|  | {12.000000,3.981072}, | 
|  | {13.000000,4.466835}, | 
|  | {14.000000,5.011872}, | 
|  | {15.000000,5.623413}, | 
|  | {16.000000,6.309574}, | 
|  | {17.000000,7.079458}, | 
|  | {18.000000,7.943282}, | 
|  | {19.000000,8.912509}, | 
|  | {20.000000,10.000000}, | 
|  | {21.000000,11.220183}, | 
|  | {22.000000,12.589254}, | 
|  | {23.000000,14.125375}, | 
|  | {24.000000,15.848933}, | 
|  |  | 
|  | }; | 
|  | #else | 
|  | T_Db_Coff coff_table[] = { | 
|  | { -96, 0.000016}, | 
|  | { -15, 0.177828}, | 
|  | { -14, 0.199526}, | 
|  | { -13, 0.223872}, | 
|  | { -12, 0.251189}, | 
|  | { -11, 0.281838}, | 
|  | { -10, 0.316228}, | 
|  | { -9, 0.354813}, | 
|  | { -8, 0.398107}, | 
|  | { -7, 0.446684}, | 
|  | { -6, 0.501187}, | 
|  | { -5, 0.562341}, | 
|  | { -4, 0.630957}, | 
|  | { -3, 0.707946}, | 
|  | { -2, 0.794328}, | 
|  | { -1, 0.891251}, | 
|  | {0, 1.000000}, | 
|  | {1, 1.122018}, | 
|  | {2, 1.258925}, | 
|  | {3, 1.412538}, | 
|  | {4, 1.584893}, | 
|  | {5, 1.778279}, | 
|  | {6, 1.995262}, | 
|  | {7, 2.238721}, | 
|  | {8, 2.511886}, | 
|  | {9, 2.818383}, | 
|  | {10, 0}, | 
|  | {11, 0}, | 
|  | {12, 3.981072}, | 
|  | {13, 0}, | 
|  | {14, 0}, | 
|  | {15, 5.623413}, | 
|  | {16, 0}, | 
|  | {17, 0}, | 
|  | {18, 7.943282}, | 
|  | {19, 0}, | 
|  | {20, 0}, | 
|  | {21, 0}, | 
|  | {22, 0}, | 
|  | {23, 0}, | 
|  | {24, 0}, | 
|  | }; | 
|  | #endif | 
|  |  | 
|  | T_Vol_Inst vol_inst = { | 
|  |  | 
|  |  | 
|  | 3,//int  rx_vol; | 
|  | 0,//int  rx_coff; | 
|  | 1,//int  rx_upflag;	//rx vol update flag | 
|  |  | 
|  | 3,//int  tx_vol; | 
|  | 0,//int  tx_coff; | 
|  | 1,//int  tx_upflag;	//tx vol update flag | 
|  | }; | 
|  |  | 
|  | int mute_flag = 0; | 
|  |  | 
|  | /**************************************************************************** | 
|  | * 	                                          Global Function Prototypes | 
|  | ****************************************************************************/ | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  | /**************************************************************************** | 
|  | * 	                                          Function Definitions | 
|  | ****************************************************************************/ | 
|  |  | 
|  | float Cal_DbCoff(float  db) | 
|  | { | 
|  |  | 
|  | float coff = 0.0f; | 
|  |  | 
|  | float tmp = (float)(db / 20); | 
|  | coff = (float) pow(10, tmp); | 
|  | printf("Cal_DbCoff db=%f,tmp=%f,coff=%f!\r\n", db , tmp , coff ); | 
|  |  | 
|  | return coff; | 
|  |  | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  | VOID Cal_ArrayDbCoff(VOID) | 
|  | { | 
|  | int  i = 0; | 
|  | int size = sizeof(coff_table) / sizeof(coff_table[0]); | 
|  | printf("update array, Db covert into Coff size=%d!\r\n", size); | 
|  |  | 
|  | for (i = 0; i < size; i++) { | 
|  | coff_table[i].coff = Cal_DbCoff(coff_table[i].gain); | 
|  | printf("update array, Db covert into Coff, db=%f,coff=%f!\r\n", coff_table[i].gain , coff_table[i].coff); | 
|  |  | 
|  | } | 
|  |  | 
|  | } | 
|  |  | 
|  | float Get_ArrayDbCoff(float  db) | 
|  | { | 
|  | int i = 0; | 
|  | float coff = 0; | 
|  | int size = sizeof(coff_table) / sizeof(coff_table[0]); | 
|  | for (i = 0; i < size; i++) { | 
|  | if (coff_table[i].gain == db) { | 
|  | coff = coff_table[i].coff; | 
|  | printf("Get_ArrayDbCoff, find db=%d,coff=%d!\r\n", db * 1000,  coff * 1000); | 
|  |  | 
|  | return coff; | 
|  | } | 
|  | } | 
|  | if (i >= DB_COFF_ARRAY_SIZE) { | 
|  | coff = Cal_DbCoff(db); | 
|  |  | 
|  | } | 
|  |  | 
|  | printf("Get_ArrayDbCoff, db=%d,size=%d,i=%d,coff=%d!\r\n", db * 1000, DB_COFF_ARRAY_SIZE, i, coff * 1000); | 
|  |  | 
|  | return coff; | 
|  |  | 
|  | } | 
|  |  | 
|  |  | 
|  | float Get_VolCoff(T_Vol_Path  volpath) | 
|  | { | 
|  | float  coff = 0.0f; | 
|  | float  gain = 0.0f; | 
|  |  | 
|  |  | 
|  | T_Wrtc_Vol_Para *volpara; | 
|  |  | 
|  | if (volpath == VOL_PATH_TX) { | 
|  |  | 
|  | if (vol_inst.tx_upflag == 0) { | 
|  | return vol_inst.tx_coff; | 
|  | } | 
|  | volpara = & vol_para; | 
|  | gain = volpara->vol[vol_inst.tx_vol]; | 
|  | coff = Get_ArrayDbCoff(gain); | 
|  | vol_inst.tx_coff = coff; | 
|  | vol_inst.tx_upflag = 0; | 
|  | } else { | 
|  |  | 
|  | if (vol_inst.rx_upflag == 0) { | 
|  | return vol_inst.rx_coff; | 
|  | } | 
|  |  | 
|  | volpara = & vol_para; | 
|  | gain = volpara->vol[vol_inst.rx_vol]; | 
|  | coff = Get_ArrayDbCoff(gain); | 
|  | vol_inst.rx_coff = coff; | 
|  | vol_inst.rx_upflag = 0; | 
|  |  | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  | return coff; | 
|  |  | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  | SINT32 Adjust_DataGain(UINT8 *pinBuffer, UINT8 *poutBuffer, UINT16 sampleNums, int mute, float gain) | 
|  | { | 
|  |  | 
|  | SINT32 ret = DRV_SUCCESS; | 
|  |  | 
|  | //float coff_f = 0; | 
|  | float coff = 0; | 
|  | int i = 0; | 
|  | short tmp = 0; | 
|  |  | 
|  | short *sinBuffer; | 
|  | short *soutBuffer; | 
|  |  | 
|  | coff = Get_ArrayDbCoff(gain); | 
|  | //coff = (int)coff_f; | 
|  |  | 
|  |  | 
|  | sinBuffer = (short  *)(pinBuffer); | 
|  | soutBuffer = (short  *)(poutBuffer); | 
|  |  | 
|  | if (mute_flag == 0) { | 
|  | for (i = 0; i < sampleNums; i++) { | 
|  | tmp = (short)coff * sinBuffer[i]; | 
|  | if ((tmp > -32768) && (tmp < 32768)) { | 
|  | soutBuffer[i] = tmp; | 
|  | } else if (tmp > 32767) { | 
|  | soutBuffer[i] = 32767; | 
|  | } else if (tmp < -32768) { | 
|  | soutBuffer[i] = -32767; | 
|  | } | 
|  | } | 
|  | } else if (mute_flag == 1) { | 
|  | for (i = 0; i < sampleNums; i++) { | 
|  |  | 
|  | soutBuffer[i] = 0; | 
|  | } | 
|  | } else { | 
|  | printf("Adjust_DataGain mute val=%d invalid!\r\n", mute); | 
|  |  | 
|  | } | 
|  |  | 
|  | return ret; | 
|  | } | 
|  |  | 
|  |  | 
|  | SINT32 Adjust_TxDataVol(UINT8 *pinBuffer, UINT8 *poutBuffer, UINT16 sampleNums) | 
|  | { | 
|  |  | 
|  | SINT32 ret = DRV_SUCCESS; | 
|  |  | 
|  | //float coff_f = 0; | 
|  | float coff = 0.0f; | 
|  | int i = 0; | 
|  | short tmp = 0; | 
|  |  | 
|  | short *sinBuffer; | 
|  | short *soutBuffer; | 
|  | #if 0 | 
|  | float gain; | 
|  | T_Webrtc_Para *para = &webrtcPara; | 
|  | //T_Webrtc_TxProcPara *procpara =&tx_procpara; | 
|  | T_Wrtc_Vol_Para *volpara = & tx_procpara.tx_vol; | 
|  | gain = volpara->vol[para->txvol]; | 
|  |  | 
|  | coff = Get_ArrayDbCoff(gain); | 
|  | //coff = (int)coff_f; | 
|  | #else | 
|  | coff = Get_VolCoff(VOL_PATH_TX); | 
|  |  | 
|  | #endif | 
|  |  | 
|  | sinBuffer = (short  *)(pinBuffer); | 
|  | soutBuffer = (short  *)(poutBuffer); | 
|  |  | 
|  | if (mute_flag == 0) { | 
|  | for (i = 0; i < sampleNums; i++) { | 
|  | tmp = (short)coff * sinBuffer[i]; | 
|  | if ((tmp > -32768) && (tmp < 32768)) { | 
|  | soutBuffer[i] = tmp; | 
|  | } else if (tmp > 32767) { | 
|  | soutBuffer[i] = 32767; | 
|  | } else if (tmp < -32768) { | 
|  | soutBuffer[i] = -32767; | 
|  | } | 
|  | } | 
|  | } else if (mute_flag == 1) { | 
|  | for (i = 0; i < sampleNums; i++) { | 
|  |  | 
|  | soutBuffer[i] = 0; | 
|  | } | 
|  | } else { | 
|  | printf("Adjust_DataGain mute val=%d invalid!\r\n", mute_flag); | 
|  |  | 
|  | } | 
|  |  | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | SINT32 Adjust_RxDataVol(UINT8 *pinBuffer, UINT8 *poutBuffer, UINT16 sampleNums) | 
|  | { | 
|  |  | 
|  | SINT32 ret = DRV_SUCCESS; | 
|  |  | 
|  | float coff = 0.0; | 
|  | int i = 0; | 
|  | short tmp = 0; | 
|  |  | 
|  | short *sinBuffer; | 
|  | short *soutBuffer; | 
|  | #if 0 | 
|  | float gain; | 
|  |  | 
|  | T_Webrtc_Para *para = &webrtcPara; | 
|  | //T_Webrtc_RxProcPara *procpara = &rx_procpara; | 
|  | T_Wrtc_Vol_Para *volpara = & rx_procpara.rx_vol; | 
|  | gain = volpara->vol[para->rxvol]; | 
|  |  | 
|  |  | 
|  | coff = Get_ArrayDbCoff(gain); | 
|  | #else | 
|  | coff = Get_VolCoff(VOL_PATH_RX); | 
|  | #endif | 
|  | sinBuffer = (short  *)(pinBuffer); | 
|  | soutBuffer = (short  *)(poutBuffer); | 
|  |  | 
|  |  | 
|  | for (i = 0; i < sampleNums; i++) { | 
|  | tmp = (short)coff * sinBuffer[i]; | 
|  | if ((tmp > -32768) && (tmp < 32768)) { | 
|  | soutBuffer[i] = tmp; | 
|  | } else if (tmp > 32767) { | 
|  | soutBuffer[i] = 32767; | 
|  | } else if (tmp < -32768) { | 
|  | soutBuffer[i] = -32767; | 
|  | } | 
|  | } | 
|  |  | 
|  | return ret; | 
|  | } | 
|  |  | 
|  |  | 
|  | SINT32 Vol_SetPara(int volpath, int  vol, int upflag) | 
|  | { | 
|  | SINT32 ret = DRV_SUCCESS; | 
|  | if (volpath == VOL_PATH_TX) { | 
|  | vol_inst.tx_vol = vol; | 
|  | vol_inst.tx_upflag = upflag; | 
|  | printf(" Vol_SetPara tx volpath=%d,upflag=%d.\n", volpath, upflag); | 
|  |  | 
|  | } else if (volpath == VOL_PATH_RX) { | 
|  | vol_inst.rx_vol = vol; | 
|  | vol_inst.rx_upflag = upflag; | 
|  | printf(" Vol_SetPara rx volpath=%d,upflag=%d.\n", volpath, upflag); | 
|  |  | 
|  | } else { | 
|  | printf(" Vol_SetPara err volpath=%d.\n", volpath); | 
|  | return DRV_ERROR; | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | SINT32 vol_SetRxVol(int vol) | 
|  | { | 
|  | SINT32 ret = DRV_SUCCESS; | 
|  | float  coff = 0.0f; | 
|  | vol_inst.rx_vol = vol; | 
|  | ret = Vol_SetPara(0,   vol, 1); | 
|  | printf(" vol_SetRxVol vol=%d,ret=%d.\n", vol, ret); | 
|  | coff = Get_VolCoff(0); | 
|  | printf(" vol_SetRxVol Get_VolCoff coff=%f.\n", coff); | 
|  |  | 
|  |  | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | int main(int argc, char **argv) | 
|  | { | 
|  |  | 
|  | printf("voltest start!\n"); | 
|  |  | 
|  | int vol = 0; | 
|  | int ret = 0; | 
|  |  | 
|  |  | 
|  | if (strcmp(argv[1], "caldb") == 0) { | 
|  |  | 
|  | Cal_ArrayDbCoff(); | 
|  |  | 
|  | } else if (strcmp(argv[1], "setvol") == 0) { | 
|  |  | 
|  |  | 
|  |  | 
|  | vol = atoi(argv[2]); | 
|  | ret = vol_SetRxVol(vol); | 
|  |  | 
|  | } else { | 
|  | return 0; | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  |