/////////////////////////////////////////////////////////////////// //// MCK/MML 初学者 指南 /////////////////////////////////////// //// by nullsleep ////////// product 8 bitpeoples ///////////// //// 版本 1.0 /////////// Research & Development ///////////// /////////////////////////////////////////////////////////////////// ***************************************************************************** ** OBJECTIVE — 目的 ****************************************************** ***************************************************************************** 此文档是有关使用 MCK/MML 设计 NES 乐曲过程中涉及的每件事和 所需规则 , 命令的参考文档 。它概要地介绍了必需的方法和步骤 , 如何开始构建 MCK/MML 工作区域 , NES 每个声音通道的程序规则 。 包括大部分共通和常用的 MML 命令及作用 , 以及制作一个 NSF 文件可能出现的问题和处理方法 。 感谢 : Izumi, Manbow-J, Norix, Virt, Memblers, 和在 MCK 2ch 的每个人 ******************************************************************************* ** MCK/MML WORKSPACE SETUP — MCK/MML 工作区设置 **************************** ******************************************************************************* 下载以下文件 ------------------------------------------------------------------------------- mck_0228.zip mckc025.zip dmcconv005.zip mckc-e.txt - 当前可探访的网址 : http://www.geocities.co.jp/Playtown-Denei/9628/ mkit251_dos.zip - 当前可探访的网址 : http://www.magicengine.com/mkit/download.html Organize MCK/MML Workspace — 构建 MCK/MML 工作区 ------------------------------------------------------------------------------- 创建一个名为 'workspace' 的文件夹 , 并解压mck_0228.zip 内的全部的文件到此文件夹 。 接着 , 解压 mckc025.zip 内的全部的文件到此文件夹 。现在从 mkit251_dos.zip 内提取 名为 nesasm.exe 的文件到 'workspace' 文件夹 。其他 magickit 的文件不是必需的 。 从 mckc zip 提取 'source' 文件夹 ,到 'workspace' 。最后 , 在 'workspace' 内创建一个 新的名为 'DMCconv' 的文件夹 , 并解压 dmcconv005.zip 文件到此文件夹 。 Create and Modify Files — 创建和修改文件 ------------------------------------------------------------------------------- 在你的 'workspace' 文件夹内 , 创建 个新的名为 songdata.mml 的文本文件 。 你将使用 MML ( music macro language ) — ( 音乐宏语言 )在这个文本文件内谱写你的乐曲 。 但是首先, 还有一些事必须设置好 。打开 make_nsf.txt 找到文件最后名为 . include 的语句 。 然后在最后的一行 , 添加以下语句 : .include "songdata.h" 在 make_nsf.txt 文件里你也可以看到下面这些语句 : .org $800E db "Song Name" db $00 .org $802E db "Artist" db $00 .org $804E db "Maker" db $00 这是 NSF 的标题部分 , 用它来识别乐曲 。应该明显看出这个 org 语句是 hex values ( 十六位 值 ) 它对每部分的空间是有限的 , 最大长度为 31 个字符 。看到在下文后你应该适当地修改这些标题区 , 注意保持在 31 个字符限定内 : .org $800E db "My First NES Chip ( 曲目名称 )" db $00 .org $802E db "Nullsleep ( 曲作者 )" db $00 .org $804E db "2003 Jeremiah Johnson ( 时间 发行人 )" db $00 ******************************************************************************* ** GENERATING THE NSF FILE — 制作 NSF 文件 ***************************** ******************************************************************************* 创建另一个新的文本文件 , 打开并输入 : mckc_e songdata.mml del nesmusic.nsf nesasm -raw make_nsf.txt ren make_nsf.nes nesmusic.nsf 保存文件后退出 , 再命名它为 build.bat 这是个简单的批处理文件 , 它将运行全部命令从 MML 数据里生成一个 NSF 文件 。 首先它利用 mckc 在 songdata.h 里转换 songdata.mml 导入大块的数据 , 之后 nesasm 将连同 MCK 声音驱动程序代码一起 , 汇编进一个 NSF 文件 。 至此每件事都应该设置妥当了 , 现在你将开始起程 !设计 MML ! ******************************************************************************* ** BASIC SONG SETUP — 基本歌曲设置 *************************************** ******************************************************************************* Header Credits — 标题声明 ------------------------------------------------------------------------------- 在你的首选的文本编辑程序内打开 songdata.mml , 第一件事是你应该 在文件的起始行加入识别注释 , 曲作者你自己和歌曲的标题 。 例如 : #TITLE My First NES Chip ( 标题 ) #COMPOSER Nullsleep ( 曲作者 ) #PROGRAMER 2003 Jeremiah Johnson ( 发行人 ) 这是可选的步骤, 但还是推荐使用它 , 尤其是你的 MML 文件是公开发布的版本 。 此外还要注意的是 , 在 MCK 内不要错误拼写 #PROGRAMER 。 Channel Layout — 通道布局 ------------------------------------------------------------------------------- NES 有 5 个( 通道 ) channels 共同工作 , 在 MML 里它们的定义项如下 : A this is the first pulse channel A 第一脉冲通道 B this is the second pulse channel B 第二脉冲通道 C this is the triangle channel C 三角波形通道 D this is the noise channel D 噪波通道 E this is the dpcm channe E dpcm 通道 这份指南将包括每个通道的程序规则 , ( 脉冲通道 )pulse channel A+B 它们的运作方式是相同的 。 Tempo Settings —( 音乐 )速率设定 ------------------------------------------------------------------------------- Tempo 设定可单独作用于每个 channel , 或许通常你需要所有的 channel 在播放时都有相同的速度保持每个件事同步 。 设置 tempo 于全部的 channel 如下 : ABCDE t150 这是在 MML 里的表示法 , 为 channels A , B , C , D , E, 设置 tempo 值是每分 150( 拍 )beats 。 tempo 的有效值是 1 -至- 255 。 Volume Settings — 音量设定 ------------------------------------------------------------------------------- ( 脉冲波型通道 )pulse wave channels (A+B) 和 ( 噪波通道 )noise channel ( D ) 在 NES 里有( 音量 ) Volume 控制 ,( 三角波型通道) triangle wave channel ( C ) 和 ( DPCM 通道 ) DPCM channel ( E ) 只能设置 ON or OFF ( 开启或断开 )。 pulse 和 noise channels , 在这里有 2 种 Volume 设置方式 。 第一个是设定恒量 volume , 使用方法如下 : A v15 设置 channel A 音量至 15 , 那是可用的最高音量 。然而 , 大部分案例 使用 ( 音量层 ) volume envelope , 相比设置恒量 volume , 或许是更好的选择 。 设置基本的 volume envelopes 很简单 。但是如果既不设定恒量 volume 也不设定 volume envelopes 来定义 pulse channels (A+B) 或 noise channel ( D ) , 那在这些通道上你将听不到任何声音输出 。这有个简单的 volume envelopes 例子 : @v0 = { 10 9 8 7 6 5 4 3 2 } volume envelope 取值在 0 -至-15 之间 。最高的 volume 为 15 , 0 为静止 。 这个 volume envelope 起始在高音量很快地衰减到一个低的音量 , 最后的值是延续声音 , 直到另一个 note ( 注释 )开始播放 。你可以轻易地修改 volume envelope 或设置更多 , 更深层的例子将在下面提供 , 包括在 envelope 内设置 ( 循环点 ) loop points 。 ******************************************************************************* ** PULSE WAVE CHANNELS (A+B) — 脉冲波型通道 ( A+B ) *********************** ******************************************************************************* Initialization — 设定初值 ------------------------------------------------------------------------------- 下一步是单独地设置每个 pulse channels ( 脉冲通道 ) 通道的属性和需求 , 例如 note length ( 注释 长度 ), octave ( 八度音阶 ), duty cycle (循环周波 ) , 和 ( 音量层 ) volume envelope 。这是个可用的 pulse wave channels 设置 : A l8 o4 @01 @v0 解译到 channel A , 设置缺省 note 长度值为 8 个 notes ,设置 octave 为 4th octave , 设置 duty cycle 为 01 (25% duty cycle ) , 使用 volume envelope 0 (上面有详细说明 )。 下面是 duty cycle 设定说明 。 Duty Cycle Explanation — Duty Cycle 说明 ------------------------------------------------------------------------------- 你可以认为 pulse wave( 脉冲波型 )相当于一个 square wave ( 方型波型 )变量宽度 。 square wave 宽度确定在 50% ( 波型中部 )。但是 pulse waves 有更多灵活性 , 所谓灵活性就是 pulse wave 的 duty cycle ( 或音色 ) 。 下面是在 NES 的 pulse wave channels 上 4 种可存在的 duty cycle 设定 。 _ 00 | | | 12.5% thin raspy sound 细薄的刺耳声音 | |_____________| ___ 01 | | | 25% thick fat sound 浓厚 , 丰满的声音 | |___________| _______ 02 | | | 50% smooth clear sound 平滑的 , 明亮的声音 | |_______| ___________ 03 | | | 75% same as 25% but phase-inverted 类似 25% 但是 相位 - 反向的 | |___| Programming the Pulse Channel — 设计脉冲通道 ------------------------------------------------------------------------------- 现在 Pulse Channel ( A ) 已完成了设置 , 在这里有个简短的 note sequence ( 注释序列 )可以执行它 。 A c d e f g4 a16 b16 >c c d e f g4 a16 b16 >c<< 如果你了解标准的音乐表示法 , 那所见的应该有几分熟悉 。 另外 , 要使用 ( 升调和降调 )sharps 和 flats , 可在任一个 note 值后加 + 或 - ( 分别地 )。 在一个 octave 内的 notes : c+ d+ f+ g+ a+ | # # | # # # | 其它: | # # | # # # | r = rest ( 休止符 ) | # # | # # # | w = wait (休止上一个 note , 但不静止 ) |__|__|__|__|__|__|__| c d e f g a b Channel A 缺省 note 长度值是 8 notes , 上面的旋律是播放 c b e f notes 每个为 8 分之一长度 , 然后是 g4 播放 g 为 4 分之一长度 , 接着是 a16 b16 播放 a note 和 b note 每个 16 分之一长度 。下个是 > 字符 , 它是上升 octave ( 八度音阶 )的转换开关 , ( 现在我们是在 5 th octave ) 于是在 5 th octave 播放 c ( 八分音符 ) note 8 。 现在数值再次重复 , 最后在结束前下降 2 octaves( 到 channel 初始设定的 4 th octave ) 。 还有 , 关于 note 持续时间 , 可使用 dotted notes ( 点 注释 ) , 应该再次复习那些标准的音乐符号的知识 。note 加 " 点 " 增加它的值一半的持续时间 。 以下例子可帮助说明 : c8. = c note played for an eighth plus a sixteenth c note 播放一个 8 分之一 加 16 分之一 d4. = d note played for a quarter plus an eighth d note 播放一个 4 分之一 加 8 分之一 e4.. = e note played for a quarter plus an eighth plus a sixteenth e note 播放一个 4 分之一 加 8 分之一 加 16 f2.. = f note played for a half plus a quarter plus an eighth f note 播放一个 2 分之一 加 4 分之一 加 8 现在 , 回到上面第一个 pulse wave channel (A) 的实例程序在 上 , 注意此 sequence ( 序列 )将只播放一次 。 可以用括号使全部 sequence 或一小部分循环 , 括号后为循环次数 。 表示在下面 : A [c d e f g4 a16 b16 >c c d e f g4 a16 b16 >c<<]2 这将 loop ( 循环 )整个 sequence 两次 。它确保你的 MML 代码整洁 , 并约去一些没必要的输入 。 让 sequence 觉得有更多的活力 , 另外 volume envelope 能设置 2 项 , 并且可以来回转变 。 完成像这样 : #TITLE My First NES Chip #COMPOSER Nullsleep #PROGRAMER 2003 Jeremiah Johnson @v0 = { 10 9 8 7 6 5 4 3 2 } @v1 = { 15 15 14 14 13 13 12 12 11 11 10 10 9 9 8 8 7 7 6 6 } ABCDE t150 A l8 o4 @01 @v0 A [c d e f @v1 g4 @v0 a16 b16 >c c d e f @v1 g4 @v0 a16 b16 >c<<]2 volume envelope 开关将在 4 分之一 notes 轻微强调 , 因为 volume 初始设置更高 , 新的 volume envelope 减缓了衰减速率 。 所有这些设置也同样应用于第 2 个 pulse channel (B) 。 ******************************************************************************* ** TRIANGLE WAVE CHANNEL (C) — 三角波形通道 (C) ************************** ******************************************************************************* Initialization — 初始设定 ------------------------------------------------------------------------------- 除了 volume envelope 和 duty cycle 参数外 , triangle wave channel ( C ) 的运作 类似 pulse wave channels 。triangle channel 没有 volume 控制 , 它只能选择 ON or OFF , 因此 volume envelopes 是不可用的 。同样 , duty cycle 设定只是应用在 pulse channels 上 , 用在 triangle channel 上将被忽略 。 这是值得注意的地方 , 初始设置 triangle wave channe 是相当地简单的 : C l4 o3 q6 解译到 channel C 缺省 note 长度值 向 4 分之一 notes , 设定 octave 为 3rd octave , 最后设定 q6 。 对于此项设置可能会困惑 , 在 channel C 上它可以轻微地切断播放 notes 。 q 的取值范围是 1 -至- 8 。 Notes 分成 8 个均等的部分 , 在切断 note 播放之前取值是 ?/8 。 例如 , 设置 q6 将剪切 6/8ths note 在之后播放 。 它会加强 basslines 的节奏感 , 如果 notes 允许声音连续 。 Programming the Triangle Channel — 设计三角波形通道 ------------------------------------------------------------------------------- 这是在 triangle channel 上 bassline sequence ( 序列 )的小例子 : C c e g8 g8 a16 b16 >c8 c e g8 g8 a16 b16 >c8<< 加入到 MML 的末端 , 4 次 ( 循环 ) loop 。先听见它同 pulse wave channel (A) 一起播放 , 然后听到它的单独演奏 。 #TITLE My First NES Chip #COMPOSER Nullsleep #PROGRAMER 2003 Jeremiah Johnson @v0 = { 10 9 8 7 6 5 4 3 2 } @v1 = { 15 15 14 14 13 13 12 12 11 11 10 10 9 9 8 8 7 7 6 6 } ABCDE t150 A l8 o4 @01 @v0 A [c d e f @v1 g4 @v0 a16 b16 >c c d e f @v1 g4 @v0 a16 b16 >c<<]2 C l4 o3 q6 C [c e g8 g8 a16 b16 >c8 c e g8 g8 a16 b16 >c8<<]4 ******************************************************************************* ** NOISE CHANNEL (D) — 噪波通道(D) ************************************ ******************************************************************************* Noise Channel Explanation - 噪波通道说明 ------------------------------------------------------------------------------- noise channel (D) 是个多用途的通道 。 它可模拟海滩波浪声 , 火箭引擎轰鸣声 , 黑暗地牢内烈焰的声音 , 等等... 补充打击乐器并稍微增强你的( 鼓 ) drum 采样 。 如同 pulse wave channels , volume envelopes 可用 noise channel 上 , 并且是获得优等音色的重要角色 。此外它有 2 种工作方式 : ( 标准的 ) normal 和 ( 循环噪波 ) looped noise 。looped noise 设置会很有趣的 , 听上去带些金属音色 。 noise channel 的 pitch 范围是非常有限的 , 并在每个 octave 上循环 。 使用 octave 变化没必要的 。c note 象是 (高 pitch ) high pitch , 梢微地往下的是 e , f , g , a , 和最后的 b note 象是( 低 pitch ) lowest pitched 。 Initialization — 设定初值 ------------------------------------------------------------------------------- 在这里是一组 简单的 volume envelopes 可用于 noise channel 上的 一些基本打击乐器 : @v2 = { 15 12 10 8 6 3 2 1 0 } @v3 = { 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 } channel 初始的 volume envelopes 设置应该是 : D l4 o1 @0 @v2 解译到 channel D , 缺省 note length 值为 4 分之一 notes , 设定 octave 为 1st octave , 设定噪波模式为 normal( @1 用 于开启 looped noise ), 使用 volume envelope 2 。 Programming the Noise Channel — 设计噪波通道 ------------------------------------------------------------------------------- 这是个简短的鼓音噪波序列 : D @v2 b @v3 e @v2 b @v3 e @v2 b @v3 e @v2 b @v3 e8 @v2 b8 添加到 MML 的末端 , 4 次 loop 。 #TITLE My First NES Chip #COMPOSER Nullsleep #PROGRAMER 2003 Jeremiah Johnson @v0 = { 10 9 8 7 6 5 4 3 2 } @v1 = { 15 15 14 14 13 13 12 12 11 11 10 10 9 9 8 8 7 7 6 6 } @v2 = { 15 12 10 8 6 3 2 1 0 } @v3 = { 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 } ABCDE t150 A l8 o4 @01 @v0 A [c d e f @v1 g4 @v0 a16 b16 >c c d e f @v1 g4 @v0 a16 b16 >c<<]2 C l4 o3 q6 C [c e g8 g8 a16 b16 >c8 c e g8 g8 a16 b16 >c8<<]4 D l4 o1 @0 @v2 D [@v2 b @v3 e @v2 b @v3 e @v2 b @v3 e @v2 b @v3 e8 @v2 b8]4 ******************************************************************************* ** DPCM CHANNEL (E) ********************************************************** ******************************************************************************* DPCM Channel Explanation DPCM 通道说明 ------------------------------------------------------------------------------- DPCM 通道, 或 delta modulation channel (DMC) , 是 NES 用来重放( 采样 )sample 的通道 。 它可应用于规划( 鼓 ) drums , sampled( 低音 ) basslines , 或( 连续的歌声 ) even vocal samples 。 DPCM 的操作简单易懂 , 只有少量参数必须调整 。同 triangle wave channel 一样没有音量控制 , DPCM 通道只能选 ON or OFF 。 NES 默认使用它的自带的 1-bit sample ( 采样 )格式 , 你也可以转换自己的 samples 。 方法在下一部分描述 。 Creating DPCM Samples — 创建 DPCM 采样 ------------------------------------------------------------------------------- DMCconv 程序将你的 . wav 采样转换至 .bin 供 MCK 使用 。 DMCconv 文件虽然不是在英语的 , 然而它的操作很简单所以应用不是问题 。 下面说明它的用法: 用法 : DMCconv wavefile outfile 选项 -r? DMC 采样等级 ( 0-F ) ( 缺省值 : F 33.14KHz ) 0: 4.18KHz 1: 4.71KHz 2: 5.26KHz 3: 5.59KHz 4: 6.26KHz 5: 7.05KHz 6: 7.92KHz 7: 8.36KHz 8: 9.42KHz 9:11.18KHz A:12.60KHz B:13.98KHz C:16.88KHz D:21.30KHz E:24.86KHz F:33.14KHz -v? 音量 ( 缺省值 : 100 ) -n 不校正音量 ( 缺省值 : Adjust ) -b 存储体填充大小 ( 缺省值 : No padding ) 例如 : DMCconv kick.wav kick.dmc 转换 kick.wav 文件至 kickdrum sample , 可用 NES 默认设置 。 Initialization and Programming the DPCM Channel — 设定初值和规划 DPCM 通道 ------------------------------------------------------------------------------- 转换全部所需的采样 , 在 'workspace' 文件夹内创建目录 'samples' 将采样文件放到此目录下 。设置如下 : @DPCM0 = { "samples\kick.dmc",15 } @DPCM2 = { "samples\snare.dmc",15 } E o0 l4 第一个(采样 ) sample , kick.dmc , 它将映射到 @DPCM0 上 , 相当于 octave 0 上的 c note 。 然后你将注意到第二个 sample , snare.dmc , 映射到 @DPCM2 相当于 octave 0 上的 d note ... 跳过 @DPCM1 是避免映射 samples sharps/flats 失控 , 保持 MML 有更强的易读性 。实例 , 哪个是下列更易识别的 kick 和 snare 鼓声? E c d c d c d c d8 c8 或 E c c+ c c+ c c+ c c+8 c8 显然应该是第一项拥有更强的易读性 , 增强可读性有利于设计更深层次 , 复杂冗长的 drum sequences 。 Looping 它并添加它到 MML 程序的末端 , 像这样 : #TITLE My First NES Chip #COMPOSER Nullsleep #PROGRAMER 2003 Jeremiah Johnson @v0 = { 10 9 8 7 6 5 4 3 2 } @v1 = { 15 15 14 14 13 13 12 12 11 11 10 10 9 9 8 8 7 7 6 6 } @v2 = { 15 12 10 8 6 3 2 1 0 } @v3 = { 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 } @DPCM0 = { "samples\kick.dmc",15 } @DPCM2 = { "samples\snare.dmc",15 } ABCDE t150 A l8 o4 @01 @v0 A [c d e f @v1 g4 @v0 a16 b16 >c c d e f @v1 g4 @v0 a16 b16 >c<<]2 C l4 o3 q6 C [c e g8 g8 a16 b16 >c8 c e g8 g8 a16 b16 >c8<<]4 D l4 o1 @0 @v2 D [@v2 b @v3 e @v2 b @v3 e @v2 b @v3 e @v2 b @v3 e8 @v2 b8]4 E o0 l4 E [c d c d c d c d8 c8]4 ******************************************************************************* ** ADDITIONAL MACROS — 附加的宏命令 ************************************** ******************************************************************************* 这部分将包含部分常用的 macros( 宏 )可以应用在你更深层和复杂曲调上 。 首先将给出 macros 的语法 , 其后是可用的有效范围或值 , 结束的例子和说明 。 更全面的 MML 命令列表 , 请查阅在此文档在开始时所提及到的 Virt 的 mckc-e.txt 。 Volume Macro @v[num] = { } — 音量 宏 @ v[num] = { } ------------------------------------------------------------------------------- 有效值范围 数目: 0 -至-127 有效值范围 参数: 0 -至-15 @v0 = { 10 8 6 5 4 3 2 | 3 4 5 6 5 4 } A @v0 c d e f g a b >c< B @v0 c d e f g a b >c< D @v0 c d e f g a b >c< volume envelope macro 在开头的已经地祥细介绍了 ,可用于 pulse wave channels (A+B) 和 the noise channel (D) 。这个例子举例说明 macro 里面的 loop point ( 循环点 )。 注意在 | 之后的 2 , 这是循环点 。 全部的值在此之后这点将 loop 。 如此例子 , channel 开始播放在 volume 10 往下是 8, 6, 5, 4, 3, 到 2 之后增加到 3, 4, 5, 峰值在 6, 然后回到 5, 4, 接着回到 3 从第 3 阶这里开始 looping 。volume macros 里的 Loop points 是很长用的 , 例如 , 模拟 ( 延迟/回声 ) delay/echo 效果 。 Timbre Macro @[num] = { } — 音色宏@[num] = { } ------------------------------------------------------------------------------- 有效值范围 数目: 0 -至- 127 有效值范围 参数: 0 -至- 3 @0 = { | 2 2 2 2 1 1 1 1 0 0 0 0 1 1 1 1 } A @@0 c d e f g a b >c< B @@0 c d e f g a b >c< Timbre Macro 仅可用在 pulse wave channels (A+B) 上 , 迅速地转换 pulse waves 的 duty cycles 。 上面的例子是在括号内起始处设置 loop point , 含意是循环全部的值 。 一个 50% duty cycle 播放 4 帧 , 其后是 25% duty cycle 4 帧 , 12.5% duty cycle 4 帧 , 跟着再次划过 25% duty cycle 4 帧 , 最后循环到起始端 50% duty cycle 。 在 pulse wave channels 上 , 用 Timbre macros 加强声音变化使声音更有趣 。 用循环 timbre macro 丰富你的乐曲提升到一个新层面 。 或使用 non-looping macro ( 非-循环宏 ) 朴实地方式 , 却让人感觉到作回本质的勇气 。 Arpeggio/Note Macro @EN[num] = { } — 琶音/注释 宏 @EN[num] = { } ------------------------------------------------------------------------------- 有效值范围 数目: 0 -至-127 有效值范围 参数: -127 -至-126 @EN0 = { 0 0 | 4 0 3 0 -7 0 } A EN0 c f g >c< ENOF B EN0 c f g >c< ENOF D EN0 c f g >c< ENOF arpeggio —( 琶音 ), ( 或 note ) macro 是用非常迅速地划过单列串行的 notes , 可用在 pulse wave channels ( A+B ) 和 the noise channel (D) 上 。 最普通使用方法大概是 , 在单个通道上模拟 ( 和音 ) chords , macro 的参数不是绝对的 , 还可替代当前的 note 。那么 , 回到上面的例子 , 起始点的 note 是播放 2 帧表示为 0 s , 接着是 loop point 设定 , loop point 后的 note 是增强的 4 半音程(如果基础 note 是 c 现在将播放 e ) , 其后的 0 保持这个新的 note 到第二帧 , 然后新的 note 是增强的 3 半音程 ( 由 e 至 g 我们假定 c 为基础的 note ) , 其后是 0 保持新的 note 到第二秒帧 , 最后减少 7 半音程 , 后退到基础 note , 下列的 0 保持到第二帧后 , 跳回 loop point 。 这例子是模拟( 大调和音 )major chord 。EN[num] 命令是在 channel 上开启 macro , 断开用 ENOF 命令 。 Pitch Macro @EP[num] = { } — Pitch 宏 @EP[num] = { } ------------------------------------------------------------------------------- 有效值范围 数目: 0 -至-127 有效值范围 参数: -127-至-126 @EP0 = { 8 } @EP1 = { -64 } A EP0 c EPOF r EP1 c EPOF B EP0 c EPOF r EP1 c EPOF C EP0 c EPOF r EP1 c EPOF D EP0 c EPOF r EP1 c EPOF 除了 DPCM channel (E) , pitch macro 可用在其它全部的 channel 上 , 作用是基于所赋值的参数 , 变化 note 的频率速度 。当数字 (s) 在括号内是正数时 , pitch 的频率将上升 。同样 , 当括号内是负数时 , pitch 里的 note 的频率 将下降 。 进一步的涵义是从 0 ( 任一方向 ) 加快频率 。在上面的例子里 , 设置了两个 pitch macros , EP0 是缓慢的上升 pitch 而 EP1 是非常极端的下降 pitch 。第二个示例里, pitch 快速地下滑 , 产生出有趣的效果 。两个例子在括号内使用单一的值 , 但是在上面的 arpeggio macro 实例里 也可使用若干的值 , 并设置 loop point 。在 channel 上使用 pitch macro 将延续保持 ON 直到发出 EPOF 命令为止 , 它才断开 。 Vibrato Macro @MP[num] = { [delay] [speed] [depth] } — 颤音 宏@ MP[num] = { [ 延迟 ] [ 速度 ] [ 深度 ] } ------------------------------------------------------------------------------- 有效值范围 数目: 0 -至- 63 有效值范围 延迟参数: 0 -至- 255 有效值范围 速度参数: 1 -至- 255 有效值范围 深度参数: 0 -至- 255 @MP0 = { 8 2 6 } A MP0 c1 d1 e1 f1 g1 a1 b1 >c1< MPOF B MP0 c1 d1 e1 f1 g1 a1 b1 >c1< MPOF C MP0 c1 d1 e1 f1 g1 a1 b1 >c1< MPOF D MP0 c1 d1 e1 f1 g1 a1 b1 >c1< MPOF vibrato ( 颤音 )( 或 pitch modulation — pitch 调控 )macro 可用在 除 DPCM channel (E) 之外 , 其它的全部 channel 上 。 在括号里有 3 个必须设置的参数 : ( 延迟 )delay, ( 速度 )speed , 和( 深度 ) depth 。 Pitch modulation 的作用是变化在( 正弦波 )sine wave 模式内 note 的频率 。 delay 参数决定等待多长时间激活( 颤音 ) vibrato , 值为 0 时立刻激活它 。 speed 参数确定 sine wave 周期 , 量多的值将减慢 pitch 变化 。 最后是 depth 参数 , 它确定 sine wave 的振幅 , 量多的值概括 pitch 范围 。同 arpeggio/note macro 和 pitch macro 一样 , vibrato 应用在 channel 上后 , 将持续开启 , 直到获得 MPOF 命令后关闭 。 ******************************************************************************* ** TROUBLESHOOTING - 排出故障 ********************************************* ******************************************************************************* DPCM Sample Problems — DPCM 采样问题 ------------------------------------------------------------------------------- DPCM samples 有时会在你的曲调内引发 ( 爆音 ) pops , 在播放 samples 前 , 或之后 , 会听得见小小的滴答声 。总是不能完全地消除这些故障 , 但你可以将问题最小化 。 首先 , DMCconv , 推荐使用 16bit 44100KHz Mono .wav 文件 , 确保在你的声音编辑器内 samples 起始和终止 level 的为 0 。校验后 , 再用 DMCconv 转换采样 , 用( 16 位 ) hex 编辑器打开转换完的 samples 。 如果文件的大小不是 16 倍数 , 应该填补 $ AA 或 $55 直到它是 。 Bank Overflows — 存储体溢出 ------------------------------------------------------------------------------- 当工作在一只长的乐曲 , 或使用 特别复杂的 MML 时 , 你也许会遇到 从 nesasm 输出的下列错误 : Bank overflow, offset > $1FFF! Nesasm 代码只有 8 K 存储体 。 如果你的( 声音数据 ) songdata 占用了很多空间 , 你将在编译时遇到( 存储体溢出 ) bank overflow 问题 。 幸运地的是 , 有一个 MML 命令 bankswitching 会给你的 songdata 更多空间 。 它的使用方法如下 : #BANK-CHANGE [num] num 的有效值范围是 1 to 14 , 每个对应 1 个 track 在你的 MML 代码里 (1=A, 2=B, 3=C, ... ) 。 如果你第一次使用命令没有成功的排除 bank overflow , 尝试 bankswitching 替换 不同的 tracks 。也可选择使用在下面的这命令 : #BANK-CHANGE [num1],[num2] num1 有效值范围是 0 -至- 2 既存储体编号 , num2 1 -至- 14 对应1个 track 编号 。 如果你使用 DPCM 通道 , num1 应该设置为 0 , 可以避开 DPCM , DPCM 的 samples 储存在 banks 1 和 2 内。 - 文件结束------------------------------------------------------------------------- ../love_always/nullsleep ../www.8bitpeoples.com ../www.nullsleep.com 如果你在此文档内发现任何错误或有任何提议或要求 , 请联系我 : nullsleep@8bitpeoples.com 相关的链接 : http://www.geocities.co.jp/Playtown-Denei/9628/ ; mck 之 家 http://www.vorc.org ; 有关 vgm & chiptune 新闻 http://nesdev.parodius.com ; 大量 NES 文档资源 http://research.8bitpeoples.com ; NES 和其他的 8bit love ^.^ Translated by 童陨翁( Tong Yun Weng )[ tongyunweng@hotmail.com ] [ http://www.freewebs.com/minifood/ ] ^.^ Chinese Edition Version : V 1.0 ^.^ 如果你在此文档中发现了错误或不足 , 请发信至我的信箱 , 对你的指正和建议 , 在这里我将提前表示感谢 。