📄 audio_pcm.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 + -