📄 record.c
字号:
#include"710defs.h"
#include"AC97.h"
#include"HB_it.h"
/*播放缓冲区的首地址*/
#define base_addres 0x100000
/*播放数据*/
UINT8 PlayData[300000] = {0};
UINT32 PCM_QUEUE_LEN = (512*1024);
UINT _uPlayVol = 0x1f1f;
UINT16 sPlayVolume = 0;
UINT16 sRecVolume = 0;
BOOL PlayLastBlock,RecDmaToggle;
volatile UINT32 _uPcmQHead, _uPcmQTail;
/*延时函数*/
static void Delay(int nCnt)
{
volatile int loop;
for (loop=0; loop<nCnt; loop++);
}
/*播放函数*/
INT Play_Callback(UINT8 *pucBuff, UINT32 uDataLen)
{
UINT nLen;
nLen = PCM_QUEUE_LEN - _uPcmQHead;
/*将数据从PCM队列中取出放到DMA缓存区*/
if (nLen >= uDataLen)
{
memcpy(pucBuff, &PlayData[_uPcmQHead], uDataLen);
_uPcmQHead = (_uPcmQHead + uDataLen) % PCM_QUEUE_LEN;
}
else
{
memcpy(pucBuff, &PlayData[_uPcmQHead], nLen);
memcpy(&pucBuff[nLen], PlayData, uDataLen - nLen);
_uPcmQHead = uDataLen - nLen;
}
return 0;
}
/*录音函数*/
INT record_callback(UINT8 *pucBuff, UINT32 uDataLen)
{
INT nLen;
//copy the input PCM into PCM queue from the DMA buffer
nLen = PCM_QUEUE_LEN - _uPcmQTail;
if (nLen >= uDataLen)
{
memcpy(&PlayData[_uPcmQTail], pucBuff, uDataLen);
_uPcmQTail = (_uPcmQTail + uDataLen) % PCM_QUEUE_LEN;
}
else
{
memcpy(&PlayData[_uPcmQTail], pucBuff, nLen);
memcpy(PlayData, &pucBuff[nLen], uDataLen - nLen);
_uPcmQTail = uDataLen - nLen;
}
return 0;
}
/* 读AC97寄存器*/
static UINT16 ac97_read_register(INT nIdx)
{
UINT volatile nWait;
/* 置起R_WB位并写入寄存器地址 */
REG_ACTL_ACOS1 = (0x80 | nIdx);
/* 设置帧是否有效和有效的时隙 */
REG_ACTL_ACOS0 = 0x11;
Delay(100);
/* 检查AC_ACTL_ACCON的AC_R_FINISH位是否被置高,若被置高,说明读数据缓存区已经准备好给CPU读取 */
for (nWait = 0; nWait < 0x10000; nWait++)
{
if (REG_ACTL_ACCON & AC_R_FINISH)
break;
}
REG_ACTL_ACOS0 = 0;
Delay(100);
return (REG_ACTL_ACIS2 & 0xFFFF);
}
/* 写AC97寄存器*/
static INT ac97_write_register(INT nIdx, UINT16 sValue)
{
volatile UINT nWait;
/* 清R_WB位并写入寄存器地址*/
REG_ACTL_ACOS1 = nIdx;
/* 写入AC97寄存器的值*/
REG_ACTL_ACOS2 = sValue;
/* 设置帧的有效位和有效的时隙*/
REG_ACTL_ACOS0 = 0x13;
Delay(100);
/* 检查AC_ACTL_ACCON的AC_W_FINISH位,若被清零,说明AC-LINK控制数据输出缓存已经被CPU移到编解码器*/
for (nWait = 0; nWait < 0x10000; nWait++)
{
if (!(REG_ACTL_ACCON & AC_W_FINISH))
break;
}
/*若读回的值和写入的值相同,则说明写入成功*/
if (ac97_read_register(nIdx) != sValue)
{while(1)
;
}
REG_ACTL_ACOS0 = 0;
return 0;
}
/*初始化AC97*/
UINT8 Initac97()
{
/*使能音频控制器和AC-LINK接口*/
REG_ACTL_CON = REG_ACTL_CON | IIS_AC_PIN_SEL | AUDIO_EN | ACLINK_EN | PFIFO_EN | RFIFO_EN | T_DMA_IRQ | R_DMA_IRQ | DMA_EN;
Delay(1000);
/*stereo模式*/
REG_ACTL_RESET = REG_ACTL_RESET | 0xf000;
/* 重启音频控制器 */
REG_ACTL_RESET = REG_ACTL_RESET | ACTL_RESET_BIT;
Delay(1000);
REG_ACTL_RESET = REG_ACTL_RESET & ~ACTL_RESET_BIT;
Delay(1000);
/* 重启AC97接口 */
REG_ACTL_RESET = REG_ACTL_RESET | AC_RESET;
Delay(1000);
REG_ACTL_RESET = REG_ACTL_RESET & ~AC_RESET;
Delay(1000);
/* 冷启动AC97 */
REG_ACTL_ACCON = REG_ACTL_ACCON | AC_C_RES;
Delay(1000);
REG_ACTL_ACCON = REG_ACTL_ACCON & ~AC_C_RES;
Delay(1000);
/* 检查AC97的ACTL_ACIS0的CODEC_READY位,若置起则说明AC97准备好了 */
if (!(REG_ACTL_ACIS0 & 0x10))
{
while(1);
}
Delay(100);
/*选择麦克 1;3D控制 关;looback 关*/
ac97_write_register(AC97_GENERAL_PURPOSE, 0);
return 0;
}
/*开始播放函数*/
UINT8 StartPlay(INT nSamplingRate)
{
/* 使能VRA(variable rate audio)并设置播放采样率*/
ac97_write_register(AC97_EXT_AUDIO_CTRL, ac97_read_register(AC97_EXT_AUDIO_CTRL)|0x1);
ac97_write_register(AC97_FRONT_DAC_RATE, nSamplingRate);
/*设置DMA基地址和目的地址长度*/
REG_ACTL_PDSTB = base_addres;
REG_ACTL_PDST_LENGTH = 0x1000;
PlayLastBlock = 0;
/* 开始播放 */
REG_ACTL_ACOS0 = 0x1c; //设置数据传输时隙有效
REG_ACTL_PSR = 0x3;
REG_ACTL_RESET = REG_ACTL_RESET | AC_PLAY;
return 0;
}
/* 设置音量 */
INT SetPlayVolume(UINT8 ucLeftVol, UINT8 ucRightVol)
{
INT nLData, nRData;
if (ucLeftVol == 0)
nLData = 0x80;
else
nLData = 31 - (ucLeftVol & 0x1f);
if (ucRightVol == 0)
nRData = 0x80;
else
nRData = 31 - (ucRightVol & 0x1f);
sPlayVolume = (nLData << 8) | nRData;
if (ucLeftVol == 0)
nLData = 0x80;
else
nLData = 62 - ucLeftVol*2;
if (ucRightVol == 0)
nRData = 0x80;
else
nRData = 62 - ucRightVol*2;
_uPlayVol = (nLData << 8) | nRData;
/* 设置音量 */
ac97_write_register(AC97_PCM_OUT_VOLUME, sPlayVolume ); //PCM数据输出音量
ac97_write_register(AC97_AUX_OUT_VOLUME, _uPlayVol); //耳机音量设置
ac97_write_register(AC97_MASTER_VOLUME, _uPlayVol); //全局音量设置
return 0;
}
void StopPlay()
{
/* 停止播放 */
REG_ACTL_RESET = REG_ACTL_RESET & ~AC_PLAY;
REG_ACTL_ACOS0 = 0;
/*关闭音频播放中断 */
REG_AIC_MDCR = REG_AIC_MDCR | 0x40;
return ;
}
/* 开始录音 */
INT StartRecord(INT nSamplingRate)
{
REG_ACTL_RESET = REG_ACTL_RESET &~RECORD_LEFT_CHNNEL &~RECORD_RIGHT_CHNNEL;
REG_ACTL_RESET = REG_ACTL_RESET | RECORD_RIGHT_CHNNEL | RECORD_LEFT_CHNNEL;
ac97_write_register(AC97_RECORD_SELECT, 0); /* record select MIC in */
/* set record vol */
ac97_write_register(AC97_RECORD_GAIN, 0x0f0f);
//ac97_write_register(AC97_MIC_VOLUME, sRecVolume | 1<<6);
ac97_write_register(AC97_RECORD_GAIN_MIC, 0x0f0f);
/* set record sampling rate */
if (nSamplingRate != 48000)
{
/* enable VRA and set sampling frequency */
ac97_write_register(AC97_EXT_AUDIO_CTRL, ac97_read_register(AC97_EXT_AUDIO_CTRL)|0x1);
ac97_write_register(AC97_LR_ADC_RATE, nSamplingRate);
}
/* set DMA record destination base address */
REG_ACTL_RDSTB = base_addres;
/* set DMA record buffer length */
REG_ACTL_RDST_LENGTH = 4096;
/* start recording */
REG_ACTL_RSR = 0x3;
REG_ACTL_RESET = REG_ACTL_RESET | AC_RECORD;
return 0;
}
/* 停止录音 */
void StopRecord()
{
/* stop recording */
REG_ACTL_RESET = REG_ACTL_RESET & ~AC_RECORD;
/* disable audio record interrupt */
REG_AIC_MDCR = REG_AIC_MDCR | 0x40;
return ;
}
/* 设置录音音量 */
INT SetRecordVolume(UINT8 ucLeftVol, UINT8 ucRightVol)
{
if (ucLeftVol == 0)
ucLeftVol = 0x80;
else
ucLeftVol = 32 - (ucLeftVol & 0x1f);
if (ucRightVol == 0)
ucRightVol = 0x80;
else
ucRightVol = 32 - (ucRightVol & 0x1f);
sRecVolume = (ucLeftVol << 8) | ucRightVol;
ac97_write_register(AC97_MIC_VOLUME, sRecVolume );
REG_ACTL_ACOS0 = 0;
return 0;
}
int main(void)
{
PCM_QUEUE_LEN = sizeof (PlayData);
_uPcmQHead = 0;
_uPcmQTail = 0;
/* 设置I/O连接到音频 */
REG_GPIO_CFG0 = 0x155;
/*// GPIO4,1:输入 GPIO0,2,3:输出 */
REG_GPIO_DIR0 = 0xd;
/*使能音频时钟 */
REG_CLKSEL = REG_CLKSEL|0x10000;
Initac97();
/* 使能AC97播放中断 */
REG_AIC_SCR6 = 0x41;
REG_AIC_MECR = 0x40;
StartRecord(12000);
SetRecordVolume(30,30);
/* 检查是否录音完成 */
while(1)
{
if (_uPcmQTail >= (PCM_QUEUE_LEN-4096))
break;
}
StopRecord();
/* 使能AC97播放中断 */
REG_AIC_SCR6 = 0x41;
REG_AIC_MECR = 0x40;
SetPlayVolume(30,30);
StartPlay(12000);
/* 检查是否播放完成 */
while(1)
{
if (_uPcmQHead >= (PCM_QUEUE_LEN-4096))
break;
}
StopPlay();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -