⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 audio_pcm.c

📁 G.711/G.726语音采集源代码
💻 C
字号:
/****************************************Copyright (c)********************************************************
**                    (c) Copyright 2004-2005, ZhaiHai guangdong china  xu.sunny
**                                   All Rights Reserved
**                                 zhiping_xu@hotmail.com
**
**-------------------------------------------File Info--------------------------------------------------------
* File          name:  Audio_pcm.c
* Last modified Date:	
* Last       Version:	1.0
* Descriptions      : 语音采集	
*			      
**----------------------------------------------------------------------------------------------------------*/
#define IN_AUDIO
#include "config.h"

//#ifdef UCOSII
//OS_EVENT *OS_ADPCM_END_Sem;				     /*定义一个信号事件*/
//#endif
//G726_ADPCM  ADPCM;
static char ADPCMFileName[16];
/***************************************************************************************************************
*                                                adpcm_init
*
* Description: 初始化ADPCM的全局变量参数
*
* Arguments  : 
*              
*
* Returns    : 如初始化通过返回TRUE
*				       
* Note       : 
***************************************************************************************************************/
uint8 ADPCM_Init(void)
{
  uint32  err;                
  uint8  temp;
  char   *pADPCM = (char *)&ADPCM; 
  char   Send_Buff1[] = {0x78,0xc0};
  char   Send_Buff [] = {0x70,0x08,0x71,0x12,0x72,0x05,0x73,0xC5,
                         0x74,0x55,0x75,0x52,0x77,0x40,0x78,0x20};
 /*char   Recv_Buff[]  = {0x80,0x55,0x81,0x55,0x82,0x55,0x83,0x55,
                         0x84,0x55,0x85,0x55,0x87,0x55,0x88,0x55}; */
  //ADPCM_CNT = 0;
  Record_Start_End_Flag = 0x00;             
  #ifdef UCOSII
	OS_ENTER_CRITICAL();
  #endif
  for (err = 0; err < sizeof(G726_ADPCM); err++)    // 初始化ADPCM变量结构为零
	 pADPCM[err] = 0x00;
 // for (ADPCM.ADPCM_SEND_CNT = 0;ADPCM.ADPCM_SEND_CNT < 64000; ADPCM.ADPCM_SEND_CNT++) 	
   //   ADPCM.ADPCM_SEND_BUFF[ADPCM.ADPCM_SEND_CNT] = 0XAA;            
  PINSEL1 = (PINSEL1 & 0X0003FFFF)|0X00; 
    
  IO0DIR = IO0DIR & (~PCM_IN);		 /* 定义它为输入(PCM_IN 为输入)    */
  
  IO0DIR = IO0DIR | PCM_OUT;		 /* 定义它为输出(PCM_OUT为输出)    */ 
  IO0CLR = PCM_OUT;
  
  IO0DIR = IO0DIR | PCM_CLK;		 /* 定义它为输出(PCM_CLK为输出)    */ 
  IO0CLR = PCM_CLK;
  IO0DIR = IO0DIR | PCM_SYC;
  IO0CLR = PCM_SYC;
   
  IO0DIR = IO0DIR | PCM_REST;        /* 定义它为输出(PCM REST 输出)    */
  IO0SET = PCM_REST;
  OSTimeDly(20); 
  IO0CLR = PCM_REST;
  OSTimeDly(20);
  IO0SET = PCM_REST; 
  
  for (err = 0; err < sizeof(Send_Buff1); err++)  // 复位编解码器L9320
    temp = SPIRWTask(Send_Buff1[err]);
  OSTimeDly(OS_TICKS_PER_SEC);
  for (err = 0; err < sizeof(Send_Buff); err++)  // 配置编解码器L9320
     SPIRWTask(Send_Buff[err]); 
    
  #ifdef UCOSII
	OS_ADPCM_END_Sem  = OSSemCreate(0);					    /*建立信号量*/
	
	if (OS_ADPCM_END_Sem != NULL)						    /*信号量成功建立*/
 
	  {
	    OS_EXIT_CRITICAL(); 
	    return TRUE;
	  }
	 else
	  {
	    OS_EXIT_CRITICAL();
	    return FALSE;
	  }
   #endif   
}
/***************************************************************************************************************
*                                                EINT0_Exception
*
* Description: 外部中断0服务程序。检测DTMF信号,第一次DTMF信号是录音开始,第二次DTMF信号是录音的结束
*
* Arguments  : 
*              
* Returns    : 
*				       
* Note       : 
***************************************************************************************************************/
void EINT0_Exception(void)
{    
  struct time AUDIO_sTime;
  VICIntEnClr = (1 << 14) | (1 << 4) | (1<<5); //禁止 EXTINT0 Timer0 Timer1中断
  EXTINT = 0X01;
  VICVectAddr = 0;              //interrupt close 通知中断控制器中断结束
  OS_ENTER_CRITICAL();
  OS_EXIT_CRITICAL();							
  ADPCM.DTMF_COUNT++;
  if (ADPCM.DTMF_COUNT == 2)
    {   	    	    
	  T1TC   = 0;
      T1TCR  = 0x00;               // 禁止计数器1计数
      T1IR  = 0XFF;
	  ADPCM.DTMF_COUNT = 0X00;
	  if (ADPCM.ADPCM_REC_CNT > 0xa000)
	  {
	  gettime(&AUDIO_sTime);
	  //ADPCM_CNT -= 0X400; // 减掉 1024 个字节的DTMF及静音数据                                                  // 获取当前时间
	  ADPCM.ADPCM_REC_CNT = ADPCM.ADPCM_REC_CNT - 1024; // 减掉 1024 个字节的DTMF及静音数据 
	  Record_End[0]  = 0X05;                      // 录音结束标志	    	    	    	    	    	    	   	    	    
	  Record_End[1]  = AUDIO_sTime.wHour;         // 录音结束时间  	    	    	    	    	    	   	    	    
	  Record_End[3]  = AUDIO_sTime.wMinute;  	    	    	    	    	    	   	    	    
	  Record_End[5]  = AUDIO_sTime.wSecond;    	    	    	    	    	    	   	    	    
	  Record_End[7]  = AUDIO_sTime.wMilliseconds; 	    	    	    	    	    	    	   	    	    
	  Record_End[9]  = 0X0f;                      // 记录文件名及MOS值长度 	    	    	    	    	    	    	   	    	    
	  Record_End[11] = 0X00;                      // MOS值寄存器
	  Record_End[15] = ADPCMFileName[0];//0
	  Record_End[16] = ADPCMFileName[1];//8
	  Record_End[17] = ADPCMFileName[2];//0
	  Record_End[18] = ADPCMFileName[3];//0
	  Record_End[19] = ADPCMFileName[4];//1
	  Record_End[20] = ADPCMFileName[5];//0
	  Record_End[21] = ADPCMFileName[6];//.
	  Record_End[22] = ADPCMFileName[7];//w
	  Record_End[23] = ADPCMFileName[8];//a
	  Record_End[24] = ADPCMFileName[9];//v
	  Record_End[25] = 0;
	  Record_Start_End_Flag = 2;
	  OSSemPost(OS_ADPCM_END_Sem); // 发送信号量 录音完毕
	  }	
	  else
	    ADPCM.ADPCM_REC_CNT = 0;										
	}
  else
	{ 	  
	  //ADPCM.ADPCM_COUNTER = 0xffffffff;
	  gettime(&AUDIO_sTime);                                       // 获取当前时间
	  sprintf(ADPCMFileName,"%02d%02d%02d.WAV", AUDIO_sTime.wHour,
	                     AUDIO_sTime.wMinute,AUDIO_sTime.wSecond); // 文件名
	  Record_Start[0] = 0X08;                                      // 接受到的数据放入缓冲区	    	    	    	    	    	    	   	    	   
	  Record_Start[1] = AUDIO_sTime.wHour;                         //  录音开始时间  	    	    	    	    	    	   	    	    
	  Record_Start[3] = AUDIO_sTime.wMinute;  	    	    	    	    	    	   	    	    
	  Record_Start[5] = AUDIO_sTime.wSecond;    	    	    	    	    	    	   	    	    
	  Record_Start[7] = AUDIO_sTime.wMilliseconds; 	    	    	    	    	    	    	   	    	    
	  Record_Start[9] = 0X00;                                      // 字节长度为零
	  Record_Start_End_Flag = 1; 	    	    	    	    	    	    	   	    	    
	  T1TC  = 0X00;
	  T1TCR = 0x01;                // 允许计数器1计数  	    
    }
  VICIntEnable = (1 << 14) | (1 << 4) | (1<<5); //允许EXTINT0 Timer0 中断 
  //VICVectAddr = 0;              //interrupt close 通知中断控制器中断结束 
  //OS_EXIT_CRITICAL();
}
/***************************************************************************************************************
*                                                EINT1_Exception
*
* Description: 外部中断1服务程序 系统待机中断输入
*
* Arguments  : 
*              
* Returns    : 
*				       
* Note       : 
***************************************************************************************************************/
void EINT1_Exception(void)
{
  VICIntEnClr = (1 << 15) | (1 << 4) | (1 << 5); //禁止 EXTINT2 Timer0 Timer1中断
  EXTINT = 0X02;  
  #ifdef UCOSII
	OS_ENTER_CRITICAL();											
  #endif 
  
  VICIntEnable = (1 << 15) | (1 << 4) | (1 << 5); //允许EXTINT2 Timer0 Timer1 中断
  VICVectAddr = 0;            //interrupt close 通知中断控制器中断结束 
  #ifdef UCOSII
    OS_EXIT_CRITICAL();
  #endif
  
}
/***************************************************************************************************************
*                                                EINT2_Exception
*
* Description: 外部中断2服务程序,
*
* Arguments  : 
*              
* Returns    : 
*				       
* Note       :如中断进入,就打开PWM AND TIMER1中断,置同步头及时钟为高
***************************************************************************************************************/
void EINT2_Exception(void)
{
    EXTINT = 0X04;                                 //清中断标志
	                                 
	VICIntEnClr = (1 << 16) | (1 << 4) | (1 << 5); //禁止 EXTINT2 Timer0 Timer1中断
	VICVectAddr = 0X00;                            //interrupt close 通知中断控制器中断结束
	#ifdef UCOSII
	OS_ENTER_CRITICAL();	
	OS_EXIT_CRITICAL();										
    #endif 
    VICIntEnable = (1 << 16) | (1 << 4) | (1 << 5); //允许EXTINT2 Timer0 Timer1 中断
}
/***************************************************************************************************************
*                                                EINT3_Exception
*
* Description: 外部中断3服务程序,检测PCM_Sync信号(PCM同步头),一帧语音数据开始录放
*
* Arguments  : 
*              
* Returns    : 
*				       
* Note       : 外部中断3是上升沿触发,发送一帧数据的第一位并且打开定时器1的中断,定时器1中断一次的频率是128K
***************************************************************************************************************/
void  EINT3_Execption(void)
{
	uint8  i;
	EXTINT = 0X08;
	VICIntEnClr = (1 << 17) | (1 << 4);	
	#ifdef UCOSII
	OS_ENTER_CRITICAL();											
    #endif 
		for (i =0; i < 8; i++)
	{
	  IO0SET = PCM_CLK;
      __asm
      {
       nop
       nop
       nop
      }
	  IO0CLR = PCM_CLK;
	  __asm
	  {
	    nop
	    nop
	    nop
	  }
	 }	
	VICIntEnable = (1 << 17) | (1 << 4);
	VICVectAddr = 0X00;                             //interrupt close 通知中断控制器中断结束
	#ifdef UCOSII
	OS_EXIT_CRITICAL();
	#endif 
}
/***************************************************************************************************************
*                                                EINT2_Exception
*
* Description: 外部中断2服务程序,检测DTMF信号,第一次DTMF信号是录音开始,第二次DTMF信号是录音的结束
*
* Arguments  : 
*              
* Returns    : 
*				       
* Note       : 如中断进入,就打开中断3,检测PCM_Sync同步头的上升沿
***************************************************************************************************************/
void PWM_Exception(void)
{
	PWMIR = 0X70F;
	PWMPC  = 0X00;
	PWMTCR = 0x00;               // 禁止计数器1计数,禁止PWM
	VICIntEnClr = (1 << 8) | (1 << 4);
	//VICVectAddr = 0X00;                          //interrupt close 通知中断控制器中断结束
	#ifdef UCOSII
	OS_ENTER_CRITICAL();
	//OS_EXIT_CRITICAL();
	#endif
    VICIntEnable   = (1 << 8)| (1 << 4);
	VICVectAddr = 0X00;                          //interrupt close 通知中断控制器中断结束
	//#ifdef UCOSII
	OS_EXIT_CRITICAL();
	//#endif
}
/***************************************************************************************************************
*                                                Timer1_Exception
*
* Description: 
*
* Arguments  : 
*              
* Returns    : 
*				       
* Note       : 
***************************************************************************************************************/
void  Timer1_Exception(void)
{    
	T1IR  = 0XFF;	
	VICIntEnClr = (1 << 5) | (1 << 4);
	#ifdef UCOSII
	OS_ENTER_CRITICAL();											
    #endif
 
	VICIntEnable   = (1 << 5) |(1 << 4);
	VICVectAddr = 0X00;            //interrupt close 通知中断控制器中断结束	
	#ifdef UCOSII
	OS_EXIT_CRITICAL();
	#endif
}
/***************************************************************************************************************
*                                                OSWriteAdpcmFile
*
* Description: 
*
* Arguments  : 
*              
* Returns    : 
*				       
* Note       : 
***************************************************************************************************************/
void OSWriteAdpcmFileTask(void *pdata)
{	  
  uint8  err;
  uint32 i;
  char   ADPCMDir[32];
  HANDLE FHandle;  
  struct time sTime;
  struct date sDate;
  pdata  = pdata;
  for (;;)
    {
	  OSSemPend(OS_ADPCM_END_Sem,0,&err);
	  VICIntEnClr = 1 << 14;
	  /*ADPCM_CNT = 0;
	  for (i = 1400;i < ADPCM.ADPCM_REC_CNT; i++)
	    {
	      ADPCM_BUFF[ADPCM_CNT] = ADPCM.ADPCM_REC_BUF[i];
	      ADPCM_CNT++;
	    }*/
	    	      
	  //OS_ENTER_CRITICAL();
	  gettime(&sTime);        // 获取当前时间
      getdate(&sDate);        // 获取当前日期
        
      sprintf(ADPCMDir,"A:\\%s\\%02d%02d%02d\\ADPCM",PS_Test_Parameter.TestMTU, sDate.wYear, 
                                                                   sDate.wMonth,sDate.wDay);//子目录          
      //sprintf(ADPCMFileName,"%02d%02d%02d.WAV", sTime.wHour, sTime.wMinute,  sTime.wSecond); // 文件名       
      OSChangeDir(ADPCMDir); 
      FHandle = OSFileOpen(ADPCMFileName, "RW");// "RW"必顺为大写 ,建立当前录音结束时间上          
	  OSFileSeek(FHandle,0, SEEK_END);//   移动文件读\写位置
      OSFileWrite(ADPCM.ADPCM_REC_BUF, ADPCM.ADPCM_REC_CNT, FHandle);
      //OSFileWrite(ADPCM_BUFF, ADPCM_CNT, FHandle);     
      OSFileClose(FHandle);
      OSAllCacheWriteBack();  // 回写缓冲区数据到CF
      OSChangeDir("A:\\"); 
      ADPCM.ADPCM_REC_CNT = 0;
	  EXTINT = 0X01;
      VICIntEnable = 1 << 14;            
      //OS_EXIT_CRITICAL();
    }    
}
/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -