| /* | 
 |  *  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; | 
 | } | 
 |  |