接
https://blog.csdn.net/pxy198831/article/details/87017571DSP TMS320C5509A 控制DDS AD9854芯片进行AM幅度调制
既然有幅度控制,自然少不了AGC即自动增益控制,
先看程序
I_Q_result = AGC_audio(dstPing[0]);
dstPing[0]是DMA通过AD芯片采样到的14位有符号音频信号数据。
通过调用AGC函数进行AGC处理,
程序如下:
int AGC_audio(int AGC_in)
{
int AGC_out;
static int dTime=0;
static float AGC_Coff=1.0;
static int maxAGC_in=0;
static int maxArrIn=0;
//隔直流
//Audio.DATA[Audio.DATA_cnt++] = AGC_in;
/*
Audio.TOTAL_DC_VALUE += AGC_in;
Audio.DATA_cnt++;
if(Audio.DATA_cnt >= AUDIO_DC_N)
{
Audio.DATA_cnt = 0;
Audio.DC_VALUE = Audio.TOTAL_DC_VALUE>>7;
Audio.TOTAL_DC_VALUE = 0;
}
AGC_in -= Audio.DC_VALUE;
*/
if(AGC_in>maxArrIn)
maxArrIn=AGC_in;
if(-1*AGC_in>maxArrIn)
maxArrIn=-1*AGC_in;
if(dTime>256)
{
if(maxArrIn maxAGC_in)
{
maxAGC_in=AGC_in;
if(maxAGC_in>1)
AGC_Coff=AUDIO_MAX_AGC_F/maxAGC_in;
}
if((-1*AGC_in)>maxAGC_in)
{
maxAGC_in=-1*AGC_in;
if(maxAGC_in>1)
AGC_Coff=AUDIO_MAX_AGC_F/maxAGC_in;
}
AGC_out=AGC_in*AGC_Coff;
if(AGC_out>AUDIO_MAX_AGC)
AGC_out=AUDIO_MAX_AGC;
if(AGC_out<-AUDIO_MAX_AGC)
AGC_out=-AUDIO_MAX_AGC;
/* if(SQ.fft_lock == UNLOCK) */
/* { */
/* sq_fft_p[SQ.audio_cnt].re = AGC_out; */
/* sq_fft_p[SQ.audio_cnt++].im = 0; */
/* */
/* if(SQ.audio_cnt>=SQ_FFT_RE_N) */
/* { */
/* SQ.fft_lock = LOCK; */
/* } */
/* } */
//fir((DATA *)&AGC_out, (DATA *)B_BP,(DATA *)&AGC_out, BP_dbuf,1,BL_BP);
//fir((DATA *)&AGC_out, (DATA *)B_HP,(DATA *)&AGC_out, BP_dbuf_out,1,BL_HP);
// AGC_out += 32767;//(AUDIO_MAX_AGC+1000)
return AGC_out;
}
这个AGC算法就是网上常见的通过不断比较现有峰值和历史峰值的大小,
确认新的峰值,并且通过峰值计算系数。
延迟时间为256,可调。这个算法可以百度”音频/话音AGC“,以后有机会再细说。
需要特别注意的是这个函数调用的时候,要修改上限值,
因为对应的ADC不一样,采样到的最大数据值也不一样。
#define AUDIO_DC_N 128 //隔直流需要的数大小
#define AUDIO_MAX_AGC 20000 //音频AGC最大值
#define AUDIO_MAX_AGC_F 20000.0
由于AD14位小于程序int16位,所以相当于对输入音频进行了一个放大AGC,
16有符号虽然能到±32768,
但是AM调制调制度不能到100%,所以选20000这个值作为最大值门限来计算。