📄 iis-s3c44b0.c
字号:
Init_IIS(isChangePLL);
Init_UDA1341();
OS_ENTER_CRITICAL();
SetISR_Interrupt(INT_BDMA0_OFFSET, BufferPlay_Done_ISR,0);
rI_ISPC=BIT_BDMA0;
rINTMSK&=(~BIT_BDMA0);
if(AudioPlayDone_Sem)
OSSemDel(AudioPlayDone_Sem, OS_DEL_ALWAYS, &err);
AudioPlayDone_Sem=OSSemCreate(2);
if(AudioRecDone_Sem)
OSSemDel(AudioRecDone_Sem, OS_DEL_ALWAYS, &err);
AudioRecDone_Sem=OSSemCreate(0);
if(AudioDMA_Sem)
OSSemDel(AudioDMA_Sem, OS_DEL_ALWAYS, &err);
AudioDMA_Sem=OSSemCreate(1);
OS_EXIT_CRITICAL();
isPlaying=FALSE;
}
/********************************************************************\
* 播放缓冲区中的数据,自动切换发送缓冲区 *
* 参数: length为播放的数据长度 *
\********************************************************************/
void PlayAudioBuffer(int length)
{
INT8U err;
if(!isPlaying){ //当前未处于播放状态,则初始化DMA,开始播放
OSSemPend(AudioDMA_Sem, 0, &err); //等待系统的BDMA0可用
/****** BDMA0 Initialize ******/
//for Source
rBDISRC0=(1<<30)+(1<<28)+(int)(&(AudioOutBuffer[nCurrentSendBuffer])); //Half word,inc,Buf
//for des
rBDIDES0=(1<<30)+(3<<28)+((int)0x1d18010); //M2IO,fix,IISFIF
//Size
//iis,reserve,done_int,not auto-reload/start,DMA enable,COUNT
rBDICNT0=(1<<30)+(1<<26)+(3<<22)+(0<<21)+(0<<20)+(length&(~0x3));
rBDICNT0 |= (1<<20);//enable
//Enable DMA
rBDCON0 = 0x0<<2;
//Tx DMA
rIISCON|=IISCON_TXDMA;
isPlaying=TRUE;
NextSendBuffer();
AudioOutBuflength[nCurrentSendBuffer]=0; //设置下一个缓冲区未就绪
return;
}
//当前处于播放状态,则设置当前缓冲区长度
AudioOutBuflength[nCurrentSendBuffer]=length;
NextSendBuffer();
}
/********************************************************************\
* 得到录音缓冲区中的数据,自动切换缓冲区 *
* 参数: length为得到的数据长度 *
\********************************************************************/
void RecAudioBuffer(int length)
{
INT8U err;
if(!isRecing){ //当前未处于录音状态,则初始化DMA,开始录音
unsigned int *pbuffer=&AudioInBuffer[nCurrentRecBuffer][0];
OSSemPend(AudioDMA_Sem, 0, &err); //等待系统的BDMA0可用
AudioInBuflength[nCurrentRecBuffer]=0; //设置当前缓冲区未就绪
rNCACHBE1= ((int)pbuffer>>12) + ( (((int)pbuffer>>12) +0x20)<<16 );//non-cachable 65KB*2
/****** BDMA1 Initialize ******/
//for Source
rBDISRC0=(1<<30)|(3<<28)|((int)0x1d18010); //M2IO,fix,IISFIF
//for des
rBDIDES0=(((unsigned int)2<<30))|(1<<28)|(int)pbuffer; //Half word,inc,Buf
//iis,reserve,done_int,not auto-reload/start,DMA enable,COUNT
rBDICNT0=(1<<30)+(1<<26)+(3<<22)+(0<<21)+(0<<20)+(length&(~0x3));
rBDICNT0 |= (1<<20);//enable
//Enable DMA
rBDCON0 = 0x0<<2;
//Rx DMA
rIISCON|=IISCON_RXDMA;
isRecing=TRUE;
NextRecBuffer(); //设置下一个要取得的缓冲区数据长度
AudioInBuflength[nCurrentRecBuffer]=AUDIO_IN_BUFFERSIZE_B;
OSSemPend(AudioRecDone_Sem, 0, &err);//等待音频采样
return;
}
NextRecBuffer();
AudioInBuflength[nCurrentRecBuffer]=length;
//当前缓冲区处于录音状态,则等待当前缓冲区录音结束
OSSemPend(AudioRecDone_Sem, 0, &err);//等待音频采样
}
/********************************************************************\
* 发送数据到音频输出缓冲区并自动播放 *
* 参数: pdata为音频数据左右声道都包括 *
* ndata为数据长度 *
* ForcePlay表示如果缓冲区未满是否强制播放 *
\********************************************************************/
void Send2AudioBuffer(unsigned char* pdata, int ndata, BOOL ForcePlay)
{
int nleftdata;
INT8U err;
unsigned char *pCurBuf;
while(ndata!=0){
pCurBuf=(unsigned char*)&(AudioOutBuffer[nCurrentSendBuffer]);
OSSemPend(AudioPlayDone_Sem, 0, &err);
nleftdata=AUDIO_OUT_BUFFERSIZE_B-nCurrentSendpos;
if(nleftdata>ndata){
//数据未填满缓冲区
memcpy(pCurBuf+nCurrentSendpos, pdata, ndata);
nCurrentSendpos+=ndata;
if(ForcePlay){ //强制播放
PlayAudioBuffer(nCurrentSendpos+ndata);
return;
}
OSSemPost(AudioPlayDone_Sem);
return;
}
//数据填满缓冲区,开始播放此缓冲区
memcpy(pCurBuf+nCurrentSendpos, pdata, nleftdata);
PlayAudioBuffer(AUDIO_OUT_BUFFERSIZE_B);
ndata-=nleftdata;
pdata+=nleftdata;
}
}
/********************************************************************\
* 读取输入的音频缓冲区数据并自动启动录音 *
* 参数: pdata为音频数据左右声道都包括 *
* ndata为数据长度 *
* ForceRec表示如果缓冲区未满是否强制录音 *
\********************************************************************/
void GetFromAudioBuffer(unsigned char* pdata, int ndata, BOOL ForceRec)
{
#if 0
int nleftdata;
unsigned char *pCurBuf;
for(;;){
pCurBuf=(unsigned char*)&(AudioInBuffer[nCurrentGetBuffer]);
nleftdata=AudioInBuflength[nCurrentGetBuffer]-nCurrentGetpos;
if(nleftdata>=ndata){
//输入缓冲区中的数据足够,
//缓冲区数据不会读完,则复制,直接返回
memcpy(pdata, pCurBuf+nCurrentSendpos, ndata);
nCurrentGetpos+=ndata;
return;
}
//输入缓冲区的数据不足,则复制剩余的数据,
//然后等待数据到来
memcpy(pdata, pCurBuf+nCurrentSendpos, nleftdata);
ndata-=nleftdata;
pdata+=nleftdata;
if(ForceRec){ //强制录制
RecAudioBuffer(ndata);
pCurBuf=(unsigned char*)&(AudioInBuffer[nCurrentGetBuffer]);
memcpy(pdata, pCurBuf, ndata);
return;
}
else{
RecAudioBuffer(AUDIO_IN_BUFFERSIZE_B);
}
}
#else
unsigned short int data;
Uart_Printf("\n");
for(;;){
while(rIISCON&IISCON_RXFIFO_NE);
data=*rIISFIF;
Uart_Printf("%d\r",data);
}
#endif
}
void Play_Back()
{
static int buffer[44100];
for(;;){
GetFromAudioBuffer((unsigned char*)buffer, sizeof(buffer), FALSE);
Send2AudioBuffer((unsigned char*)buffer, sizeof(buffer), FALSE);
}
}
void Audio_Test()
{
Init_Audio(FALSE);
if(!Play_WavFile("1.wav"))
Uart_Printf("\nerror file!");
if(!Play_WavFile("1.wav"))
Uart_Printf("\nerror file!");
Play_Back();
}
#define WAVEFILEHEAD_RIFF 0x46464952
BOOL Play_WavFile(char filename[])
{
static int buffer[100];
U32 nbyte;
FILE *pfile;
pfile=OpenOSFile(filename, FILEMODE_READ);
if(!pfile)
return FALSE;
ReadOSFile(pfile, (U8*) buffer, 0x16*2);
if(buffer[0]!=WAVEFILEHEAD_RIFF) //invalid data
return FALSE;
while(1){
nbyte=ReadOSFile(pfile, (U8*) buffer, sizeof(buffer));
if(nbyte==sizeof(buffer))
Send2AudioBuffer((unsigned char *) buffer, nbyte, FALSE);
else{
Send2AudioBuffer((unsigned char *) buffer, nbyte, TRUE);
break;
}
}
CloseOSFile(pfile);
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -