上传我的文档
下载
收藏
行走广告与地产十六年,全国拥有推广营销经验60余个地产项目之成绩,对当下新媒体推广有独到策略思考
下载此文档
正在努力加载中...
Microchip开发工具快速手册指南
下载积分:580
内容提示:Microchip开发工具快速手册指南
文档格式:PDF|
浏览次数:8|
上传日期: 15:38:24|
文档星级:
该用户还上传了这些文档
Microchip开发工具快速手册指南
官方公共微信求大神们告诉我gba4ios的gba格式游戏可以去哪些网站上下无毒_百度知道请问有人玩过GBA的创造球会吗?求大神帮助_百度知道掌上游戏机开发指南 GBA探索日记(9)
掌上游戏机开发指南 GBA探索日记(9)
这一节我们讨论如何正常结束声音播放的问题。不要觉得这是个小问题,当初这个小问题难倒了我们所有研究GBA的爱好者。我总觉得这一点似乎是GBA设计上的缺陷,但是最后我们可以通过使用VBlank中断还解决这个问题。本篇结束的时候,我还会给出完整声音播放的代码。这样,你甚至不必了解声音播放的细节就可以实现声音的播放功能了。 由于声音播放使用的DMA不能根据WORD COUNT来控制传输的数据量,同时又不能在传输完毕的时候产生DMA中断,所以我们无法知道什么时候DMA把我们的音频数据传输完毕。这样,我们必须自己另外加一计时器,来计算什么时候声音播放结束。当然,你可以使用Timer来做,但是另外再设置个Timer似乎就麻烦了点,而且Timer的精度过高,也不好计算长时间的声音播放。依照官方开发包中的做法,我们就拿VBlank中断作为声音播放的计时器。 VBlank中断是在硬件扫描屏幕V方向扫描线的时候产生的硬件中断。它是严格的每秒59.78次(接近60次/s) 下面我们来看看这段修改后的播放声音的代码。需要注意拿他和前一节的播放代码来比较一下,看看他们之间有什么不同。 这个PlayDirectSoundA的播发函数多了一个参数u32 time.它就是用来控制声音结束的时间参数。它的单位是秒(对于一般的声音播放来说,秒单位应该是足够精确了)。 soundATime = time * 59.727; 这条代码是将实际播放时间的秒数转换成一共要产生VBlank的中断数。前面说过,我们将使用VBlank来判断我们的声音是否播放结束。而VBlank中断的频率是59.727Hz,也就是说一秒中要产生59.727次。比如说如果我们的这段声音要播放5秒钟,那么播放过程中一共要产生5*59.727次VBlank中断。这样,我们只要使用一个计数器,每次VBlank中断产生的时候计数器自加1,当它等于5*59.727的时候,那么声音也就应该结束了。 其它的代码就差不多和前一节的PlayDirectSoundA差不多了。 ////////////////////////////////////PlayDirectSoundA///////////////////////////////////// // time是播发时间,单位是秒数 void PlayDirectSoundA(u8 *sound, u16 sampleRate, u32 length,u32 time) { //Stop any previous sample soundAPlaying = 0; *(vu16 *)REG_TM0CNT_H = 0; *(vu16 *)REG_TM0CNT_L = 0; *(vu32 *)REG_DMA1SAD = 0; *(vu16 *)REG_DMA1CNT_H = 0; *(vu32 *)REG_DMA1DAD = 0; //Output DirectSound A to right channel *(vu16 *)REG_SOUNDCNT_H |= DSOUND_A_RIGHT_CHANNEL| DSOUND_A_TIMER_0 | DSOUND_A_LEFT_CHANNEL | DSOUND_A_FIFO_RESET | DSOUND_A_OUTPUT_FULL; //Enable all sound *(vu16 *)REG_SOUNDCNT_X |= SOUND_MASTER_ENABLE; //DMA1 Source Addresss *(vu32 *)REG_DMA1SAD = (u32) //Set sound A's current sound soundA = //Set the length, looping, etc soundALength = // 讲time秒转换成V-Blank中断次数,V-Blank中断是59.727Hz soundATime = time * 59.727; soundACurrent = 0; soundASampleRate = sampleR //DMA1 Destination Address (REG_SGFIFOA) *(vu32 *)REG_DMA1DAD = 0x40000A0; //Write 32 bits into 0x (REG_SGFIF0A) every VSync *(vu32 *)REG_DMA1CNT = DMA_DEST_FIXED | DMA_REPEATE | DMA_32 | DMA_TIMEING_SYNC_TO_DISPLAY | DMA_ENABLE; //Sample Rate *(vu16 *)REG_TM0CNT_L = 65536 - (/sampleRate); //Enable the timer *(vu16 *)REG_TM0CNT_H = TIMER_ENABLE | TIMER_IRQ; //The sound is playing soundAPlaying = 1; } 在这里我们增加了一个函数UpdateDirectSoundA.它的作用是判断Direct Sound A是否播放完毕的函数.它的代码很简单.每调用它一次,当前计数器soundACurrent自加1,同时判断是否播放完毕. /////////////////////////////////////UpdateDirectSoundA//////////////////////////////// void UpdateDirectSoundA(void) { // if now is not playing sound A,return if(!soundAPlaying) // Increase the Current timer soundACurrent +=1; // If sound A play time is up,close the sound A if(soundACurrent >= soundATime) CloseDirectSoundA(); } 需要注意的是,这个函数的调用必须是放在VBlank中断的响应函数里.比如像下面一样,把它的调用放在Interrupt中处理VBlank的部分里.这样我们才能保证它是每1/59.727秒被调用一次. 关于中断的部分,请看看前面的<>有关中断的部分. void Interrupts(void) { u16 Int_F REG_IME = 0x00; // Disable interrupts Int_Flag = REG_IF; // Read the interrupt flags if((REG_IF & 1) == 1) { UpdateDirectSoundA(); } REG_IF = Int_F // Write back the interrupt flags REG_IME = 1; // Re-Enable interrups } 好了.这个如何控制声音播放结束的问题总算解决了.其实我们也可以使用Timer用同样的原理来控制声音播放的结束,不过至少我觉得Timer的中断产生频率太快,完全没有必要.下面我将把我播放声音的全部代码公布出来,你可以将它拷贝到libsound.c和libsound.h,然后就可以使用了. 随便在结束本节之前再说几句,我们关于GBA的基础部分也就结束.但是我们对于GBA开发的探索还没有结束.后面的GBA探索日记将介绍一些实际游戏开发过程中需要的技术,比如汉字显示,Tile模式下写点等问题.不过这些问题就和我们一直走的官方开发包没有关系(无论是日本人还是老美根本不会去考虑汉字显示的问题),但是这些技术在实际开发过程中是很有用的.特别是汉字显示和Tile下写点这两个问题,是很多朋友都在做的,现在应该说是比较成熟的,所以在后面的两篇日记里,我也将它们公布出来,希望对大家有所帮助. //************************************* // 文件名: libsound.h // GBA中Direct Sound处理函数或宏 // tangl_99 创建于 //************************************* #ifndef _SOUND_H #define _SOUND_H //////////////////////////Necessary Includes///////////////////////////// //////////////////////////////Definitions///////////////////////////////// #define BIT00 1 #define BIT01 2 #define BIT02 4 #define BIT03 8 #define BIT04 16 #define BIT05 32 #define BIT06 64 #define BIT07 128 #define BIT08 256 #define BIT09 512 #define BIT10 1024 #define BIT11 2048 #define BIT12 4096 #define BIT13 8192 #define BIT14 16384 #define BIT15 32768 #define TIMER_CASCADE BIT02 #define TIMER_IRQ BIT06 #define TIMER_ENABLE BIT07 #define DMA_ENABLE 0x #define DMA_INTERUPT_ENABLE 0x #define DMA_TIMEING_IMMEDIATE 0x #define DMA_TIMEING_VBLANK 0x #define DMA_TIMEING_HBLANK 0x #define DMA_TIMEING_SYNC_TO_DISPLAY 0x #define DMA_16 0x #define DMA_32 0x #define DMA_REPEATE 0x #define DMA_SOURCE_INCREMENT 0x #define DMA_SOURCE_DECREMENT 0x #define DMA_SOURCE_FIXED 0x #define DMA_DEST_INCREMENT 0x #define DMA_DEST_DECREMENT 0x #define DMA_DEST_FIXED 0x #define DMA_DEST_RELOAD 0x
H3C认证Java认证Oracle认证
基础英语软考英语项目管理英语职场英语
.NETPowerBuilderWeb开发游戏开发Perl
二级模拟试题一级模拟试题一级考试经验四级考试资料
港口与航道工程建设工程法规及相关知识建设工程经济考试大纲矿业工程市政公用工程通信与广电工程
操作系统汇编语言计算机系统结构人工智能数据库系统微机与接口
软件测试软件外包系统分析与建模敏捷开发
法律法规历年试题软考英语网络管理员系统架构设计师信息系统监理师
高级通信工程师考试大纲设备环境综合能力
路由技术网络存储无线网络网络设备
CPMP考试prince2认证项目范围管理项目配置管理项目管理案例项目经理项目干系人管理
Powerpoint教程WPS教程
电子政务客户关系管理首席信息官办公自动化大数据
职称考试题目
就业指导签约违约职业测评
招生信息考研政治
网络安全安全设置工具使用手机安全
3DMax教程Flash教程CorelDraw教程Director教程
Dreamwaver教程HTML教程网站策划网站运营Frontpage教程
生物识别传感器物联网传输层物联网前沿技术物联网案例分析
互联网电信IT业界IT生活
Java核心技术J2ME教程
Linux系统管理Linux编程Linux安全AIX教程
Windows系统管理Windows教程Windows网络管理Windows故障
组织运营财务资本
视频播放文件压缩杀毒软件输入法微博
数据库开发Sybase数据库Informix数据库
&&&&&&&&&&&&&&&
希赛网 版权所有 & &&