LPC1768 WAV播放器 笔记

发布者:JoyfulSerenade最新更新时间:2018-07-24 来源: eefocus关键字:LPC1768  WAV播放器 手机看文章 扫描二维码
随时随地手机看文章

实验使用的是LPC1768   DMA + 10bit DAC作为音频信号输出,使用USB HOST 读取U盘中存储的WAV格式的音频文件,读取和播放数据文件使用的是乒乓算法。

WAV文件格式见:http://blog.csdn.net/seeker_zeroone/article/details/17526523(备注: 网络转载)

以下是根据文件格式定义的结构图。

typedef struct  RIFF_HEADER
{
uint32_t RiffFlg; //RIFF
uint32_t FileSize; //整个文件大小(不包含 RiffFlg FileSize)
uint32_t FileType; //WAVE 
}WAV_HEADER;


typedef struct FORMAT
{
uint32_t FmtFlg; //FMT
uint32_t FmtSize; // 0X16 或者 0X18,0X18 表示有附加信息 
uint16_t FmtTag; //编码方式 0x0001
uint16_t ChN; //声道 1-单声道  2 双声道
uint32_t Samples; //采样频率
uint32_t AvgBytes; //每秒所需字节数
uint16_t BlockAlign; //块对起
uint16_t AvrBits; //每个采样所需要的bit
uint16_t ROF; //附加信息——由SIZE决定 
}WAV_FORMAT;




typedef struct  FACT_BLOCK   //选项
{
uint32_t FactFlg; //FACT
uint32_t FactSize; 
}WAV_FCTBLOCK; 


typedef struct DATA_BLOCK
{
uint32_t DataFlg; //DATA
uint32_t DataSize; 
}WAV_DATA;


typedef struct Inf
{
uint32_t StartAddr; //文件头地址 
uint32_t EndAddr; //文件尾地址
uint32_t DataSize;
// uint32_t IndexF; //读文件地址 
uint8_t *pIndexB; //缓存读取地址 
// uint16_t FmtTag; //编码方式 
// uint16_t ChN; //通道 
uint32_t Samples; //采样频率 
// uint32_t AvgBytes; //每秒种采样字节数
// uint16_t BlockAlign; //数据块对齐单位(每个采样需要的字节数)
// uint16_t BitsPerSample; //每个采样需要的bit数
uint16_t *pBuff; //缓存
uint8_t State; //状态 
uint8_t Flag; //有效标志 
uint16_t PlayWords; //
uint8_t PlayPingPeng; //
}WAV_INF;

加载文件信息,识别该文件是符合规则的WAV文件,这里只允许单声道  PCM 编码 16位量化精度 的WAV文件播放。

uint8_t WAV_LoadFileMsg(void)
{
#if USB
   FRESULT res;
   uint32_t re;
#endif
uint16_t Temp,Index,Data,*pData;
uint32_t IDFlag;
WAV_HEADER *pHWav;
WAV_FORMAT *pFWav;
WAV_FCTBLOCK *pFctWav;
WAV_DATA *pDatWav;
WAV_File.StartAddr =(uint32_t)File1_Sec * (uint32_t)Sec_SIZE;
WAV_File.pIndexB =(uint8_t *)WAVBuff;
#if (USB)
res = f_read(&usbfile0,WAVBuff,BUFF_SIZE,&re);
if((res != FR_OK)||(re != BUFF_SIZE))
{
UART0_Printf("文件读取失败,错误代码 %d \r\n",res);
}
#endif
pHWav =(WAV_HEADER *)WAV_File.pIndexB;
IDFlag =('R') | ('I' << 8) | ('F' << 16) | ('F' << 24);
if(IDFlag !=pHWav->RiffFlg)
{
UART0_Printf("RIFF logo 未找到!\r\n");
return FALSE;

IDFlag =('W') | ('A' << 8) | ('V' << 16) | ('E' << 24);
if(IDFlag !=pHWav->FileType)
{
UART0_Printf("WAVE logo 未找到!\r\n");
return FALSE;
}
WAV_File.EndAddr = 8  +  pHWav->FileSize + WAV_File.StartAddr;
WAV_File.pIndexB +=sizeof( WAV_HEADER );
pFWav =(WAV_FORMAT *)WAV_File.pIndexB;
IDFlag =('f') | ('m' << 8) | ('t' << 16) | (' '<< 24);
if(IDFlag!= pFWav->FmtFlg)
{
UART0_Printf("fmt logo 未找到!\r\n");
return FALSE;
}
if( pFWav->FmtTag!=WAVE_FORMAT_PCM) 
{
UART0_Printf("不是PCM格式编码\r\n");
return FALSE;
}
if( pFWav->ChN != 0x01)
{
UART0_Printf("不是单声道\r\n");
return FALSE;
}
if( pFWav->AvrBits != 0x10)
{
UART0_Printf("量化分辨率不是16 Bit\r\n");
return FALSE;
}
WAV_File.BitsPerSample  =pFWav->AvrBits;
WAV_File.Samples =pFWav->Samples;
UART0_Printf("采样率是 %d bps \r\n",pFWav->Samples * pFWav->AvrBits);
WAV_File.pIndexB +=0x1a; //sizeof(WAV_FORMAT);====>有点问题待处理
if(pFWav->FmtSize == 16) WAV_File.pIndexB -=2; 
pFctWav =(WAV_FCTBLOCK *)WAV_File.pIndexB;
IDFlag =('f') | ('a' << 8) | ('c' << 16) | ('t' << 24);
if(IDFlag == pFctWav->FactFlg)
{
WAV_File.pIndexB +=pFctWav->FactSize + sizeof(WAV_FCTBLOCK); 
}
pDatWav =(WAV_DATA *)WAV_File.pIndexB; 
IDFlag =('d') | ('a' << 8) | ('t' << 16) | ('a' << 24);
if(IDFlag  != pDatWav->DataFlg)
{
UART0_Printf("没有找到 data logo \r\n");
return FALSE;
}
Index =WAV_File.pIndexB - (uint8_t *)WAVBuff;
WAV_File.PlayWords =BUFF_SIZE  - Index;
WAV_File.DataSize =pDatWav->DataSize -WAV_File.PlayWords; 
WAV_File.PlayWords >>=1;
WAV_File.PlayPingPeng =PlayPeng;
WAV_File.pBuff =WAVBuff + BUFF_HalfSize;
WAV_File.pIndexB =(uint8_t *)WAVBuff + Index;
pData =(uint16_t *)WAV_File.pIndexB; 
for(Temp=0;Temp{
Data = *(pData + Temp);
if(Data & 0x8000) //负数
{
Data =(~Data) + 0x8001; 
}
else //正数
{
Data +=0x8000;
}
WAV_File.pBuff[Temp] = Data & 0xffc0;

return TRUE;
}

加载波形文件数据

uint8_t WAV_LoadData(void)
{
#if USB
   FRESULT res;
   uint32_t re;
#endif
uint16_t ReadSize;
if(WAV_File.DataSize)

if(WAV_File.DataSize > BUFF_SIZE)

ReadSize =BUFF_SIZE;
}
else
{
ReadSize =WAV_File.DataSize; 
}
WAV_File.DataSize   -=ReadSize;
WAV_File.PlayWords =ReadSize >> 1;
if(WAV_File.PlayPingPeng == PlayPeng)
{
WAV_File.pBuff =WAVBuff;
#if USB
  res = f_read(&usbfile0,(void *)WAV_File.pBuff,ReadSize ,&re);
if((res != FR_OK)||(re != ReadSize))
{
  UART0_Printf("读文件失败\r\n");
}
for(re=0;re{
if( WAV_File.pBuff[re] & 0x8000) //负数
{
WAV_File.pBuff[re] =(~ WAV_File.pBuff[re]) + 0x8001; 
}
else //正数
{
WAV_File.pBuff[re] +=0x8000;
}
}
#endif
if(WAV_File.DataSize) 
{
WAV_File.PlayPingPeng =PlayPing;
}
else
{
WAV_File.PlayPingPeng =PlayEnd;
}
}
else if(WAV_File.PlayPingPeng ==PlayPing)
{
WAV_File.pBuff =WAVBuff + BUFF_HalfSize;
#if USB
  res = f_read(&usbfile0,(void *)WAV_File.pBuff,ReadSize ,&re);
if((res != FR_OK)||(re != ReadSize))
{
  UART0_Printf("读文件失败\r\n");
}
for(re=0;re{
  if( WAV_File.pBuff[re] & 0x8000) //负数
{
WAV_File.pBuff[re] =(~ WAV_File.pBuff[re]) + 0x8001; 
}
else //正数
{
WAV_File.pBuff[re] +=0x8000;
}
}
#endif 
if(WAV_File.DataSize) 
{
WAV_File.PlayPingPeng =PlayPeng;
}
else
{
WAV_File.PlayPingPeng =PlayEnd;
}


return TRUE;

return  FALSE; 
}


关键字:LPC1768  WAV播放器 引用地址:LPC1768 WAV播放器 笔记

上一篇:STM32F4 FFT 音乐频谱 不要太easy!
下一篇:LPC1768 -- RTC实时时钟

推荐阅读最新更新时间:2024-03-16 16:09

lpc1768的系统时钟
#define XTAL_FREQ 12000000 #define VECT_TAB_OFFSET 0x0000 void SystemInit(void) { //PLL0时钟配置 LPC_SC- SCS = 0X00000020; /*使能外部主晶振,频率范围1-20M*/ if (LPC_SC- SCS & (1 5)) /* 主时钟被使能 */ { while ((LPC_SC- SCS & (1 6)) == 0);/* 等待主晶振使能并稳定 */ } LPC_SC- CCLKCFG = 0x00000003; /*
[单片机]
LPC1768菜鸟学习之时钟配置
LPC1768的时钟源可以来自三个: 1)内部RC振荡器 内部振荡器可看作看门狗定时器的时钟源,也可作PLL0和cpu的时钟源,但是无法作为usb的时钟源,因为精度达不到。而且如果CAN波特率高于100kb/s,则也不适用了。在系统上电时,LPC1768都使用内部振荡器,直到软件将其切换为另一种可用的时钟源。 2)主振荡器 主振荡器可作为CPU的时钟源,需要通过分频和倍频进行配置使用。基本会使用主振荡器作为时钟源 3)RTC振荡器 RTC振荡器可提供1Hz-32kHz的RTC时钟输出,可用作PLL0、CPU和看门狗定时的时钟源。 LPC1768时钟配置会涉及到以下几个过程: 1)时钟源选择 时钟源的选择就涉及到了SCS寄存器的
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
热门活动
换一批
更多
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

更多精选电路图
换一换 更多 相关热搜器件
更多每日新闻
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved