TI中文支持网
TI专业的中文技术问题搜集分享网站

AIC23扬声器驱动没有声音

各位前辈,我在用DSP5509A做音频的采集与播放的时候,当输出白噪声时,扬声器能够正常发出声音,但是通过FIR滤波后扬声器不能发出声音,检测了一下白噪声的输出数值和FIR滤波后的输出数值,相差不大,为什么经过FIR滤波处理后的数值不能输出呢?

程序如下:

/*移位子函数*/
/*实现功能:将x6=x5,x5=x4,这样逐步移动,x0用于接收新的数据,丢弃高数据*/
int ShiftArray(float *Sx,float lastx,int T)//ANC模块,移位操作
{

  for(i=T-1;i>0;i–)
  {
     Sx[i]=Sx[i-1];
  }
  Sx[0]=lastx;
  return(0);
}

/*FIR滤波子函数*/
/*用于将信号与次级传函相滤波*/

float dotProd(float *Firx,float *Firh)
{

   float sum;
   sum=0.0;
   float stemp;
   stemp=0.0;
   for(i=0;i<N;i++)
   {
     stemp=Firx[i]*Firh[i];
     sum=sum+stemp;         //此处进行右移位操作的话
   }
   return(sum);
}

/*FXLMS算法子函数*/
float fxlms(float *xx,float *XX,float ee)     //*xx代表与wn的卷积,用于求输出yn;*XX代表与LMS算法相乘,用于更新滤波器权系数
{
   float yy;
   yy=0.0;
   float temp;
   temp=0.0;
   for(i=0;i<N;i++)
   {
      yy+=xx[i]*wn[i];
   }
   ErrorSignal_anc=ee-yy;
   temp=MMu*ErrorSignal;
   for(i=0;i<N;i++)
   {
      wn[i]=wn[i]+temp*XX[i];
   }

   return(yy);
}

/*次级通道辨识子函数*/
void LMS_Filter()
{

   float alpha;
   /*————-构造当前时刻参考信号向量————*/
   /*
   for(i=NN;i>0;i–)
   {
      x[i]=x[i-1];
   }
   x[0]=(float)whiteNoise/32768;     //对白噪声信号进行类型转换及归一化得到参考信号
   */
   /*进行滤波计算*/
   float y=0.0; //滤波器输出信号
   for(i=0;i<NN;i++)
   {
   y=y+w[i]*CZ[i];
   }
    /*计算误差信号,更新滤波器系数*/
    ErrorSignal=desizedSignal-y;
    alpha=Mu*ErrorSignal;
    for(i=0;i<NN;i++)  //更新权值
    {
      w[i]=w[i]+alpha*CZ[i];
    }

}
void main()
{
    int outputTemp,inputTemp;
    float output;
    t=0;
    //int y[N];
   // float xn=0.0,Xn=0.0,en=0.0;
    int time_flag;
    time_flag=1;            /*辨识程序开始标志*/
    CSL_init();
       PLL_config(&myConfig);       //锁相环配置,CPU时钟频率设置为144MHZ
       /*修改寄存器IVPH,IVPD,重新定义中断向量表*/
       /* Initialize CSL library – This is REQUIRED !!! */

           /* Set IVPH/IVPD to start of interrupt vector table */
           /*修改寄存器IVPH,IVPD,重新定义中断向量表*/
           IRQ_setVecs((Uint32)(&VECSTART));

           /* Temporarily disable all maskable interrupts */
          /*禁止所有可屏蔽的中断源*/
          old_intm = IRQ_globalDisable();

          /* Open Timer 0, set registers to power on defaults */
          /*打开定时器0,设置其为上电的的默认值,并返回其句柄*/
          mhTimer0 = TIMER_open(TIMER_DEV0, TIMER_OPEN_RESET);

          /* Get Event Id associated with Timer 0, for use with */
          /* CSL interrupt enable functions.                    */
          /*获取定时器0的中断ID号*/
          eventId0 = TIMER_getEventId(mhTimer0);

          /* Clear any pending Timer interrupts */
          /*清除定时器0的中断状态位*/
          IRQ_clear(eventId0);

          /* Place interrupt service routine address at */
          /* associated vector location */
          /*为定时器0设置中断服务程序*/
          IRQ_plug(eventId0,&timer0Isr);

          /* Write configuration structure values to Timer control regs */
          /*设置定时器0的控制与周期寄存器*/
          TIMER_config(mhTimer0, &timCfg0);

          /* Enable Timer interrupt */
          /*使能定时器的中断*/
          IRQ_enable(eventId0);

          /* Enable all maskable interrupts */
          /*设置寄存器ST1的INTM位,使能所有的中断*/
          IRQ_globalEnable();

          /* Start Timer */
          /*启动定时器0*/
          TIMER_start(mhTimer0);
       aic_23init();     //初始化AIC23芯片
       sdram_init();     //初始化SDRAM外部存储器
       int temp;//存储器配置
       /*初始化辨识参数*/
       n_iden=0;         //定义辨识次数
       N_iden=7000;      //设置辨识次数上限,最多8000,改大需修改CMD文件中的相关值
       timer_flag=0;              //定时器状态标志位初始化
       Mu=0.1;                      /*次级通道辨识,收敛步长,可修改此值,改大加快收敛速度,注意发散,Q15表示定标*/
       MMu=0.001;                     /*ANC模块收敛步长*/
       /*初始化滤波器权系数,辨识部分*/
       for(i=0;i<NN;i++)
       {
           w[i]=0.0;
       }
/*初始化ANC模块参数*/
       for(i=0;i<N;i++)
       {
           xn[i]=0.0;          //ANC模块估计参考信号初始化,存储滤波器阶数这么大的数组,xn=en-yn*hn
           wn[i]=0.0;          //ANC模块LMS滤波器权系数初始化
           h[i]=0.0;           //ANC模块次级通达函数初始化,由次级通道估计赋值而来,h=w
           x_lms[i]=0.0;       //ANC模块输入到LMS算法的输入信参考信号,x_lms=xn*hn
           yn[i]=0.0;          //ANC模块经过LMS滤波器后得到的扬声器输出信号,用于驱动扬声器,yn=xn*wn
           yn_e[i]=0.0;        //ANC模块LMS滤波后与次级传函的滤波后的数据,用于估计参考信号yn_e=yn*hn
       }
    /*回放音频*/
 while(1)
 {
     if(time_flag==1)           //次级通道辨识标志
     {
         time_flag=0;           //次级通道辨识置0
         while(n_iden<N_iden)   //次级通道辨识次数应小于设定次数
         {
             for(i=0;i<NN;i++)
             {
             whiteNoise=rand()-0x4000;   //生成白噪声信号,取值范围-16384至16383
                                      while(!MCBSP_xrdy(hMcbsp)){};
                                      MCBSP_write16(hMcbsp,whiteNoise);    //输出白噪声信号,每次一个值
                                      anc_outTemp[t]=whiteNoise;
                                      while(!MCBSP_rrdy(hMcbsp)){};
                                      temp=MCBSP_read16(hMcbsp);           //读取白噪声信号,每次读取一个值
                                      desizedSignal=(float)temp/32768; //对输入信号进行类型转换及归一化得到期望信号,即进行Q定标操作
                                      CZ[i]=desizedSignal;
             }
                                      LMS_Filter();  //调用LMS自适应滤波程序
                                      //ErrorSignal_H[n_iden]=ErrorSignal;    //记录LMS滤波过程中,残余误差信号,用于绘制收敛图和导出数据

                                      n_iden=n_iden+1;                      //辨识次数增加
         }
         /*将辨识得到的次级通道传递函数赋值给ANC模块的次级通道估计,存在问题:每次调用ANC模块均要重新赋值,需要解决*/
         for(i=0;i<NN;i++)
         {
             h[i]=w[i];
         }
     }
     else
     {
         ANC_flag=1;                      //将ANC标志位置1,以便于启动标志位,考虑用中断替代
             if(ANC_flag==1)
             {
                 if(t<ANC_iden)          //限制ANC降噪次数,实际可取消一直降噪
                 {
                 ANC_flag=0;              //开始ANC模块后将标志位置0,可优化
                              while(!MCBSP_rrdy(hMcbsp)){};
                                inputTemp = MCBSP_read16(hMcbsp);      //读取误差麦克风的值,每次读取一个
                                DesiredSignal=(float)inputTemp/32768;
                                y_e=dotProd(yn,h);             //计算当前时刻到达yn经过次级传函到达en的值,用于估计参考信号,即y_e=yh*h
                                x_0=DesiredSignal-y_e;         //计算当前时刻的参考信号估计值
                                ShiftArray(xn,x_0,N);          //将当前时刻的参考信号通过移位操作进入参考信号数组
                                x_lms_0=dotProd(xn,h);         //计算进去LMS算法的参考信号当前值,x'n=xn*h
                                ShiftArray(x_lms,x_lms_0,N);   //将计算得到的当前时刻的进入LMS算法的估计参考信号通过移位操作送入到估计参考信号数组中,用于LSM算法
                                output=fxlms(xn,x_lms,DesiredSignal);  //调用LMS算法,当前计算输出值
                                ShiftArray(yn,output,N);     //将当前输出值通过移位操作进去yn数组,用于估计参考信号
                                outputTemp=(int)(output*327680);         //将计算得到的扬声器输出值送至扬声器
                               // anc_outTemp[t]=outputTemp;                 //存储输出到扬声器的值,用于查看并修正输出

                                while(!MCBSP_xrdy(hMcbsp)){};
                                MCBSP_write16(hMcbsp,outputTemp);   //将输出信号经过扬声器进行输出
                                t=t+1;     //记录ANC模块运行次数
             }
             }
    }
  }
}

mangui zhang:

对数据做做频谱分析吧看数据差不多是看不出来的

,

Susan Yang:

DSP5509A的问题请您到 C5000™ 超低功耗 DSP 发帖询问,谢谢

,

Susan Yang:

DSP5509A的问题请您到 C5000™ 超低功耗 DSP 发帖询问,谢谢

,

user6559028:

你白噪声训练收敛吗

赞(0)
未经允许不得转载:TI中文支持网 » AIC23扬声器驱动没有声音
分享到: 更多 (0)