用C语言开发NES游戏(CC65)15、音乐

粘贴到CSDN格式没调,想看格式好的点下面

https://happysoul.github.io/nes/nesdoug/

我前段时间写了一篇关于NES Audio文章。

https://nesdoug.com/2015/12/02/14-intro-to-sound/ (往下翻,在后面有翻译)

 

我们不需要对声音寄存器了解太多,我们使用Famitracker编音乐,用Famitone 2 v1.15播放音乐,我的例子中都包含famitone代码,这就足够用的了。

你需要做的就是把音乐数据文件包含在music_data下的crt0.s文件中。

 

我对音乐制作不是很擅长,你可以看看这个

 

https://youtu.be/UbGfosQHfm0

(墙外地址,以后有空再搬运油管的视频)

 

我很喜欢这个工具,famitone2还是有些局限性。

 

(这些东西有些专业,暂时不翻译了,以后再说)

 

 

 

1、No volume column.

2、Allowed notes are C-1..D-6, Note Cut

3、Only Volume, Arpeggio, and Pitch sequences

4、All instruments should have a volume envelope assigned

5、no Duty sequence

6、64 instruments max

7、no fx except Tempo Fxx, Looping backwards Bxx, and ending the frame early D00

8、Up to 17 sub songs in a file

 

 

 

由于没有音量的列,你制作的时候需要使用不同的乐器(最大的音量不同)来制作音乐。

将每首歌放到同一个文件夹中,使用“module properties”添加歌曲

 

 

一切都完成后,导出一个txt文件。您需要使用famitone2程序text2data.exe处理此文件。使用命令行,并添加-ca65开关,以便我们的汇编器在读取它时不会有任何问题。如果你想看看它们的样子,我把/ MUSIC中的所有文件都留了下来。

 

 

我写了2段音乐并放到了游戏中。

 

music_play(0) 播放第一段音乐

music_play(1) 播放第二段音乐

 

按 START 按钮切换音乐

 

neslib代码自动更新音频寄存器以匹配歌曲。在nmi代码的末尾,每帧调用一次FamiToneUpdate。

 

暂停音乐 music_pause(1)

继续播放 music_pause(0)

停止音乐 music_stop()

 

PS:我写了一个方法用来改变音乐的播放速度。通常情况下你只能在famitracker文件中设置速度。

比如boss战的时候我们希望音乐加速播放,或者是受伤等状态需要减速播放音乐,都可以使用上面的方法轻松实现

set_music_speed()

数字越小意味着越快,越大意味着越慢。6是默认值。

 

https://github.com/nesdoug/18_Music

 

 

另外,还有其他音乐驱动程序。

 

Pently,有一些游戏用了这个工具,如果你喜欢使用乐谱写音乐,可能这个是一个比较好的选择。他使用描述语言,用音乐宏(MML)或者LilyPond

 

https://github.com/pinobatch/pently

 

 

ggsound 是另一个选择,NESmaker这个软件使用了这个(使用方式不详)

https://github.com/gradualgames/ggsound

 

完整的famitracker驱动程序是另一种选择,但它非常大,比其他驱动程序慢一点。你可以从shiru的示例文件中获取它。

https://shiru.untergrund.net/files/src/cc65_neslib_famitracker.zip

 

您可以查看cppchriscpp的示例代码

https://github.com/cppchriscpp/nes-starter-kit/tree/master/source/neslib_asm/ft_drv

 

我还写了2个关于famitone的非官方更新

https://nesdoug.com/2018/09/05/links-and-misc/

 

 


 

 

声音介绍

 

你可能会为NES使用APU发声的功能犯愁,但是用了Famitracker以后,这一切都变得简单了。

 

下载SnoBrow开发的Sound Test NES

http://nesdev.com/sndtest.zip

 

他可能无法兼容所有的模拟器,FCEUX上运行没问题。

 

按 SELECT 按键切换声道,按 START 按键会触发声音播放。

该程序中,通道0=方波1,通道1=方波2,通道3=三角波,通道4=噪声

 

声音寄存器映射到$ 4000-4017

 

4000-4003 =方波1寄存器

 

4004-4007 =方波2寄存器

 

4008-400b =三角波寄存器

 

400c-400f =噪声寄存器

 

4010-4013 = DMC频道

 

4015 =控制音频输出

 

4017 =帧计数器

 

从http://wiki.nesdev.com/w/index.php/APU 搬运来的

 

4000-4003 = Square 1 channel

 

4000 = DDLC VVVV

 

D =占空比,改变声波的形状(10=平滑,01 或 11 =ok,00=annoying......让我想起Atari的声音)。

 

L =循环(重复声音)

 

C =等容体

 

V =音量(有时)

 

如果L或C都没有设置,他开始的时候声音很大,然后声音变小,再变小。。。

如果您将音符长度设置为0000 1(在寄存器4003中),你可以听到音量变化。V =音符长度,V为0时候还是会有声音。

 

如果设置了L(而C不设置),则V =重复声音的速度。较小的V =较快的重复声音。(满音量)0的V是快速的哔哔声。

 

如果设置了C和L,V将控制通道的音量,并且音符将无限播放,直到您将另一个值写入4000.这实际上是它在音乐代码中一直设置的方式。您可以通过计算帧来控制长度,通过每帧更改音量来创建音量包络,并通过设置音量为零或频率为零来结束音符。 要使方形通道静音,请将音量设置为零($ 4000 = $ 30)。

 

4001 - 频率扫描寄存器

 

4001 = EPPP NSSS

 

E =打开频率扫描

 

P =更小=更快的扫描

 

N = 0 =向下扫描,1 =向上扫描

 

S =更小=更快的扫描

 

请注意,一旦到达扫描结束,即使您将其设置为不断播放,音符也会停止。设置扫描和循环将重复几次,直到扫描结束。这可以产生很酷的效果。

 

4002 = TTTT TTTT =音符频率的低字节

 

4003 = LLLL LTTT

 

L =影响音符的长度,假设您没有将其设置为播放常量音符 (L&C均设置为4000)。非常奇怪的设置。0000 1 =很长的音符。

 

T =音符频率的高3位。

 

注意:为了播放最低音符,必须设置N标志($ 4001)(例如,某些游戏在扫描关闭时写入$ 7f到$ 4001)。

 

另外:可播放的最高音符是000..0000 1000.任何频率更高(例如000..0000 0111)将从Square 1频道产生静音。你不会想要它更高,它在较高频率范围内非常烦人。

 

-----------

 

4004-4007 = Square 2 Channel,与Square 1完全相同。

 

-----------

 

4008-400b =三角形通道

 

4008 - CRRR RRRR(C =常数,无限音符)

 

R =很奇怪。更改这些数字似乎会影响音符的长度。只需将此值设置为$ ff表示常量音符,将$ 80设置为off(静音)。如果设置为$ 7f,则长度将由$ 400b的L位控制。(感谢Pokun 纠正我)。

 

4009 - 未使用。

 

400a - TTTT TTTT - 音符频率的低字节

 

400b - LLLL LTTT - 频率的长度和高位...有关详细信息,请参见Sq 1通道。

 

注意 - 三角形通道没有音量控制。此外,它将比方形通道上的相同设置低1个八度音程。与方形通道不同,三角形频率可以高于000 0000 1000(例如000 0000 0100),并且播放非常高的音高。

 

----------

 

400c-400f =噪声通道

 

400c - xxLC VVVV - 与方波通道相同,但没有占空比。

 

400d - 未使用

 

400e - Z - - - TTTT

 

Z =如果为0,听起来像白噪声

 

如果是1,听起来像金属铿锵声

 

T =音符频率,更多=更低。频率为零将播放最高音调。

 

400f - LLLL L - - - -

 

L =影响音符的长度,假设未设置为播放常量音符(L&C均设置)。

 

要使噪声通道静音,请将音量设置为零($ 400c = $ 30)。

 

-----

 

DMC频道,是一种低采样率的声音压缩。最快的采样率提供了合理的音质,但占用了大量的ROM空间。较慢的采样率占用较少的空间,但是具有恼人的高音调嗡嗡声和较低质量的声音。

 

谨慎使用DMC。您也可以使用非常短的循环样本,这可能适用于Bass Notes。我认为DMC最常见的用途是改进鼓声,以及听起来像人类语音的单个单词 - “战斗”。

 

4010 - IL- - RRRR

 

I =设置DMC触发的IRQ

 

L =循环样本

 

R =采样率(F =最高)

 

4011 - xDDD DDDD =加载。基本上是样本的起始值,这里的一些设置将使样本更安静。这也可以用来(通过不断改变值)来制作高质量的PCM声音。

 

4012 - AAAA AAAA =样本的地址......

 

%11AA AAAA.AA00 0000

 

因此,最低地址是11000000 00000000 = $ C000

 

...最高地址是11111111 11000000 = $ ffc0。

 

注意,DMC样本必须位于$ c000和$ ffff之间。您可以使用Famitracker制作样品。

 

4013 - LLLL LLLL =样本长度......

 

%LLLL.LLLL 0001

 

最小的样本是10001 = $ 11字节。最大的样本是$ ff1字节。(你可以背靠背地播放样本,如果它太短了)。

 

4015 - 控制打开哪些通道。使用此功能启动和停止DMC通道。

 

4015 - - - 5 4 3 2 1

 

1. Square 1

 

2. Square 2

 

3. Triangle

 

4. Noise

 

5. DMC

 

4017 - 我从来没有学过这是为了什么,除了大多数游戏的启动代码在开始时存储0x40,我想要关闭某种IRQ。

 

-------

 

对于前4个通道,注释将在其最后一个寄存器被写入时触发... 4003触发方形1,4007触发方形2,400b - 三角形,400f噪声。反复写入这些(每一帧)可能会产生令人不快的点击。

 

要触发DMC声音,首先将$ 0f写入4015,然后将$ 1f写入4015.或者,如果DMC样本已结束,仅将$ 1f写入4015将重新触发样本进行播放。

 

------

 

额外的声道。一些高级映射器(特殊盒式磁带)具有额外的声道。例如,VRC7拥有更先进的FM合成芯片(仅用于1游戏,Lagrange Point)。

 

-------

 

PCM,即。高品质的声音。我从来没有尝试过这个,但我的理解是,你可以通过将值一遍又一遍地写入4011来模拟高质量的声音。这将花费大量的CPU,以至于在这种情况下运行游戏逻辑是不可能的。也许它可以在静态标题屏幕上完成。

 

--------

 

让我们添加一些快速声音代码,只是为了好玩。如果需要,将其插入其中一个课程的无限循环中。确保声道已打开...

 

*((unsigned char *)0x4015)= 0x0f;

 

//快速哔 -

 

if(((joypad1old&START)== 0)&&((joypad1&START)!= 0)){

 

*((unsigned char *)0x4000)= 0x0f;

 

*((unsigned char *)0x4003)= 0x01;

 

}

 

 

 

//扫频效果 - 跳跃声音

 

if(((joypad1old&START)== 0)&&((joypad1&START)!= 0)){

 

*((unsigned char *)0x4000)= 0x0f;

 

*((unsigned char *)0x4001)= 0xab;

 

*((unsigned char *)0x4003)= 0x01;

 

}

 

 

 

//噪音测试 -

 

if(((joypad1old&START)== 0)&&((joypad1&START)!= 0)){

 

*((unsigned char *)0x400c)= 0x0f;

 

*((unsigned char *)0x400e)= 0x0c;

 

*((unsigned char *)0x400e)= 0x00;

 

}

 

对于SoundTest程序随便用用就好,然后立即忘记一切,转到用Famitracker。

 

这一段随便看看就好,直接谷歌翻译的,作者都不太建议看太细,了解点就够了,直接用工具就好

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值