📄 wave.c
字号:
//====================================================================================
//文 件 名:Wave.c
//功能描述: Wave文件播放程序
//维护记录:
// 2007.01.17 V0.1 by wangtao <wangtao@sunnorth.com.cn>
//====================================================================================
#include "SPCE3200_Register.h"
#include "SPCE3200_Constant.h"
#include "DAC.h"
#include "Resource.h"
unsigned short HalfBuffer_Flag; // 前/后半个Buffer标志
unsigned short *Buffer_BA; // 保存Buffer地址
unsigned short Ex_Buffer[512]; // 开4K外部Buffer
unsigned short *WAVE_Addr; // 语音资源地址指针
unsigned short *WAVE_EndAddr;
unsigned short Wave_Status;
//=========================================================================
// 语法格式:void SP_Wave_Init(void)
// 实现功能: 初始化函数,用来使能DAC及其中断
// 参数: 无
// 返回值: 无
//=========================================================================
void SP_Wave_Init(void)
{
*P_INT_MASK_CTRL1 &= (~C_INT_DAC_DIS); // DAC中断使能
*P_DAC_CLK_CONF = C_DAC_CLK_EN // 打开DAC模块时钟
| C_DAC_RST_DIS; // 不复位DAC模块
*P_DAC_MODE_CTRL1 = ~(C_DAC_CTRL_DIS // 使能DAC模块
| C_DAC_OUTPUT_DIS); // 使能DAC输出
Wave_Status = 0;
HalfBuffer_Flag = 0;
}
//=========================================================================
// 语法格式:void SP_Wave_Setup(unsigned short *WAVE_SA,unsigned int SampleRate)
// 实现功能: DAC的参数设置、Buffer地址设定;并先填满8KByte的Buffer后使能通道
// 参数: WAVE_SA,语音资源的起始地址;SampleRate,采样率
// 返回值: 无
//=========================================================================
void SP_Wave_Setup(unsigned short *WAVE_SA, unsigned short *WAVE_EA, unsigned int SampleRate, short Channel)
{
unsigned short WAVE_Data; // 保存语音资源数据
unsigned int i; // 用作循环
unsigned short *Buffer_Addr; // Buffer指针,用来填Buffer
*P_DAC_FIFOBA_LOW = ((unsigned int)Ex_Buffer); // 设置外部Buffer基地址 低16位
*P_DAC_FIFOBA_HIGH = ((unsigned int)Ex_Buffer) >> 16; // 高16位
*P_DAC_SAMPLE_CLK = 27000000/SampleRate - 1; // 设置采样率
*P_DAC_INT_STATUS = C_DAC_INT_EN // DAC中断使能
| C_DAC_STEREO_MODE // setero模式
| C_DAC_BUFFER_1K; // Buffer大小为1K
Buffer_BA = (unsigned short*)(((unsigned int)Ex_Buffer) & 0x8FFFFFF); // 地址的低29位有效
WAVE_Addr = WAVE_SA; // 从语音资源的起始地址开始
WAVE_EndAddr = WAVE_EA;
Buffer_Addr = Buffer_BA; // Buffer指针指向外部Buffer
//----------------------------去掉wave文件的头--------------------------//
WAVE_Addr += 16;
WAVE_Data = *WAVE_Addr;
if(WAVE_Data!=0x0018)
WAVE_Addr = WAVE_SA+0x3A;
else
WAVE_Addr = WAVE_SA+0x3C;
for(i=0;i<256;i++) // 填4K双字节的Buffer
{
WAVE_Data = *WAVE_Addr; // 从语音资源地址取语音数据
WAVE_Data ^= 0x8000; // 变为无符号数
WAVE_Addr++; // 语音资源指针指向下一个地址
*Buffer_Addr = WAVE_Data; // 填Buffer/16位数据
Buffer_Addr++; // Buffer指针指向下一个地址
*Buffer_Addr = WAVE_Data; // 填Buffer/16位数据
Buffer_Addr++; // Buffer指针指向下一个地址
}
*P_DAC_MODE_CTRL2 = C_DAC_FIFO_EN; // 使能DAC的FIFO
if(Channel & 0x01) // 使能通道0
*P_DAC_MODE_CTRL2 |= C_DAC_CHANNAL0_EN;
if(Channel & 0x02) // 使能通道1
*P_DAC_MODE_CTRL2 |= C_DAC_CHANNAL1_EN;
Wave_Status = 1;
}
//=========================================================================
// 语法格式:void SP_Fill_ExBuffer()
// 实现功能: 填外部Buffer,一次填半个Buffer
// 参数: WAVE_SA,语音资源的起始地址
// 返回值: 无
//=========================================================================
void SP_Fill_ExBuffer(void)
{
unsigned short WAVE_Data; // 保存语音资源数据
unsigned int i; // 用作循环
unsigned short *Buffer_Addr; // Buffer指针,用来填Buffer
if(Wave_Status==0)return;
Buffer_Addr = Buffer_BA;
for(i=0;i<128;i++) // 填2K双字节的Buffer(一半Buffer)
{
WAVE_Data = *WAVE_Addr; // 从语音资源地址取语音数据
WAVE_Data ^= 0x8000; // 变为无符号数
WAVE_Addr++; // 语音资源指针指向下一个地址
if(WAVE_Addr <= WAVE_EndAddr) // 如果还没有播放结束地址
{
*Buffer_Addr = WAVE_Data; // 填Buffer/16位数据
Buffer_Addr++; // Buffer指针指向下一个地址
*Buffer_Addr = WAVE_Data; // 填Buffer/16位数据
Buffer_Addr++; // Buffer指针指向下一个地址
}
if(WAVE_Addr >= WAVE_EndAddr) // 如果播放到结束地址
{
Wave_Status = 0;
*P_DAC_INT_STATUS = ~C_DAC_INT_EN;
*P_DAC_MODE_CTRL2 &= ~(C_DAC_FIFO_EN // 使能DAC的FIFO
| C_DAC_CHANNAL0_EN // 使能通道0
| C_DAC_CHANNAL1_EN) // 使能通道1
;
}
}
if(HalfBuffer_Flag != 0) // 指向前半个Buffer
{
Buffer_BA -= 256;
HalfBuffer_Flag = 0;
}
else // 指向后半个Buffer
{
Buffer_BA += 256;
HalfBuffer_Flag = 1;
}
}
//=========================================================================
// 语法格式:unsigned int SP_Play_Status(void)
// 实现功能: 获得播放状态
// 参数: 无
// 返回值: 播放状态
//=========================================================================
unsigned int SP_Play_Status(void)
{
return Wave_Status;
}
//=========================================================================
// 语法格式:void SP_Wave_Stop(void)
// 实现功能: 停止播放
// 参数: 无
// 返回值: 无
//=========================================================================
void SP_Wave_Stop(void)
{
Wave_Status = 0;
Wave_Status = 0;
*P_DAC_INT_STATUS = ~C_DAC_INT_EN;
*P_DAC_MODE_CTRL2 &= ~(C_DAC_FIFO_EN // 使能DAC的FIFO
| C_DAC_CHANNAL0_EN // 使能通道0
| C_DAC_CHANNAL1_EN) // 使能通道1
;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -