基于YM3812的简易MIDI合成器(芯片部分)
注意:文章中有些公式目前显示不出来
前言
本文主要是对芯片做介绍,之后还有设计思路,成品展示以及如何调制出想要音色的教程。本中会出现大量专有名词的编者图省事而自创的词,前者有不懂的话建议配合搜索引擎阅读,后者,,,,,看编者之后能不能想到更形象的词来替代了,强烈建议配合数据手册去查看。
附:一些用这个简易合成器播放的音乐:
μs-爱上你万岁
残酷天使的行动纲领(这首除了鼓组以外都是)
芯片介绍
YM3812(OPL2)是一款在1985年由雅马哈研发基于FM音频合成的音乐芯片,其广泛使用在以IBM PC 为载体的独立声卡上。其中最著名的就是ADLIB声卡,当年一些低端的雅马哈电子琴上也可以见到该芯片。该芯片有⑨个通道,每个通道由两个振荡器组成。或者由6个声道和5种打击乐器组成。每个振荡器都可以产生正弦波,也可以将其修改为其他3种波形:一种是像半波整流后的波形,一种是像全波整流后的波形,还有一种是伪锯齿波。这种奇怪的产生波形的方式为YM3812提供了独特的声音,对于上个世纪80年代中后期的游戏爱好者来说,该芯片产生的独特声音可以说是刻在了DNA当中。
关于FM合成
这个编者也是三脚猫功夫,就不在这献丑了:),感兴趣的可以看这篇文章
有能者也可以看看John Chowning教授关于FM音频合成的论文
简单说一下吧,FM调制原理大概就是用一个信号去调制另一个信号的频率。说白了这里的FM跟我们平常听的FM广播是一个东西,只不过广播的频率不在人的听觉频率范围内且我们听到的是解调过后的信号,而这里提到的FM频率是在人的听觉范围内且我们听到的是调制后的信号。
芯片介绍(建议配合数据手册查看)
数据手册及相关资料:
YM3812选型手册
YM3812应用手册
YM3014数据手册
首先来看芯片管脚功能
总览
1.ΦM
芯片主时钟输入
2.ΦSY*SH
外置DAC控制信号,因为YM3812内部没有集成DAC,所以需要配套的DAC YM3014输出信号。
SY:DAC的主时钟;
SH:同步时钟。
3.D0~D7
8位并行数据输入
4.CS*RD*WR*A0
这四位控制芯片读写操作
注意:这里的读取读取的是YM3812的中断状态寄存器,其他寄存器不能读取
5.IRQ
默认低电平,当芯片的定时器溢出时产生中断信号(低电平)。这个中断信号可以被程序屏蔽。
6.IC
复位芯片,包括清除所有寄存器中的值。
7.MO
YM3812的13位串行数字音频信号输出,需要外置DAC转化。
8.GND,VCC
地和电源。
读写控制
a):Inactive Mode(停用模式)
CS位置1,数据线D0~D7为高阻态,此时芯片不接收数据。
b):Address Write Mode(写地址模式)
当芯片位于此模式,数据线接受的数据视作寄存器地址。
注意:切换到此模式后需要等待至少12个主时钟周期才能进行下一步操作
c): Data Write Mode(写数据模式)
当芯片位于此模式,数据线接受的数据视作值写入选中的寄存器。
注意:切换到此模式后需要等待至少84个主时钟周期才能进行下一步操作
d):Status Read Mode(状态读取)
当芯片位于此模式,读取中断状态寄存器的值并发送到数据线上。
e):Inhibit(禁止模式)注1
当芯片位于此模式,数据线上的数据均视为无效。
芯片通道设置
在介绍之前,需要再提一下FM合成相关知识。
之前说过,FM调制是用一个信号去调制另一个信号的频率,也就是说需要一个东西去产生这两个信号。在YAMAHA生产的FM合成芯片中,这个东西叫做运算子(operator)注2。算子是芯片中产生信号的最小单位,每个算子产生一个信号,芯片内部通过将多个算子以不同的形式相连接来产生不同特征的信号。
YM3812有⑨个FM音频通道,这意味着可以同时发出⑨个声音,每一个音频通道有两个运算子。值得注意的是,实际上在YM3812内部只有一个算子,所有的音频通道通过复用这一个算子来产生声音。那么如何控制这9个通道呢,在YAMAHA生产的FM合成芯片中,是通过槽(slot)来控制发声通道。
由上图可以看到,每个通道对应两个槽(第一二行),这里槽就代替了算子实现了控制信号的功能。而表格中第三行指的是槽之间的联系,1是指调制波注3,2指载波注3。倒数两行是不同槽对应的寄存器地址,通过向寄存器中写入数据控制槽输出的信号频率。
寄存器介绍
注:($xx)指寄存器地址
总览
中断状态寄存器:
| D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
| IRQ | FLG T1 | FLG T2 | \ | \ | \ | \ | \ |
1.TEST
雅马哈测试芯片用的,没用
2.定时器
YM3812中有两个定时器,Timer1最多支持80us延时,Timer2支持320us。当定时器溢出时,IRQ拉低。
计算公式:
a):Timer1($02)
主频率为3.6Mhz时:
| D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
$$
延时时间:Tov(ms) ={ (256-\mathbf{N}1)0.08\
\mathbf{N}1 = \mathbf{D}727+....+\mathbf{D}1*2+\mathbf{D}_0}
$$
b):Timer2($03)
主频率为3.6Mhz时:
| D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
$$
延时时间:Tov(ms) = (256-\mathbf{N}2)0.32\
\mathbf{N}2 = \mathbf{D}727+....+\mathbf{D}1*2+\mathbf{D}_0
$$
c):TimerControl($04)
此寄存器控制定时器1,2的启停和溢出动作。
| D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
| IRQ RESET | MASK T1 | MASK T2 | \ | \ | \ | ST2 | ST1 |
ST1:控制定时器1启停
ST2:控制定时器2启停,功能与定时器1相同
MASK T2:置1时,定时器2无溢出动作
MASK T1:置1时,定时器1无溢出动作
IRQ RESET:重置定时器1,2
3.芯片工作模式选择($08)
| D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
| CSM | NOTE SEL | \ | \ | \ | \ | \ | \ |
CSM:置1语音合成模式,置0音乐模式
注:语音合成模式用不到。
NOTE SEL:这一位控制键盘分割点(类似电子琴的键盘分割功能)。置0时,由F-Number(后面会讲)的高两位控制音符8度;置1时由F-Number低八位控制。
4.AM/VIB/EG-TYP/KSR/Multiple($20~35)
| D7 | D6 | D5 | D4 | D3 D2 D1 D0 |
| AM | VIB | EG-Typ | KSR | MULTIPLE |
1):MULTIPLE:载波和调制波的倍频系数。参数如下表:
| MUL | Multiple | MUL | Multiple | MUL | Multiple | MUL | Multiple |
| 0 | 1/2 | 4 | 4 | 8 | 8 | C | 12 |
| 1 | 1 | 5 | 5 | 9 | 9 | D | 12 |
| 2 | 2 | 6 | 6 | A | 10 | E | 15 |
| 3 | 3 | 7 | 7 | B | 10 | F | 15 |
MUL:填入寄存器的值
Multiple:倍频系数
公式:
$$
输出信号F(t) = Esin(ωft+Isin(iωft))
$$
ωf:信号频率(F-number)
I:载波倍频系数
i:调制波倍频系数
2):KSR:键缩放率。通过改变ADSR包络中的AD速率使得芯片发出的声音更接近真正乐器的声音(大致意思)
| D4 | N | Rks | N | Rks | N | Rks | N | Rks |
| 0 | 0 | 0 | 4 | 1 | 8 | 2 | 12 | 3 |
| 0 | 1 | 0 | 5 | 1 | 9 | 2 | 13 | 3 |
| 0 | 2 | 0 | 6 | 1 | 10 | 2 | 14 | 3 |
| 0 | 3 | 0 | 7 | 1 | 11 | 2 | 15 | 3 |
| 1*1 | 0 | 0 | 4 | 4 | 8 | 8 | 12 | 12 |
| 1*1 | 1 | 1 | 5 | 5 | 9 | 9 | 13 | 13 |
| 1*1 | 2 | 2 | 6 | 6 | 10 | 10 | 14 | 14 |
| 1*1 | 3 | 3 | 7 | 7 | 11 | 11 | 15 | 15 |
注:N为键缩放数
$$
RATE = 4*R+Rks
$$
3):EG-TYP:控制尾音消失的方式。置1时键盘什么时候松开声音什么时候消失;置0时声音在键盘按下时逐渐消失。
4):VIB:置1时启用低频振荡器产生颤音感,颤音深度由$BD寄存器控制。
5):AM:置1时启用低频振荡器轻微改变信号振幅,改变振幅的深度由$BD寄存器控制。
5.KSL/TOTAL LEVEL($40~55)
| D7 D6 | D5 D4 D3 D2 D1 D0 |
| KSL | Total level |
1):Total level:每个槽的信号振幅大小,可以理解为音量大小。
注:所需音量可由下列公式得到:
$$ Volume = 0 - (24D5+12D4+6D3+.....+0.75D0)dB $$
2):KSL:一些乐器的响度会伴随着音调的升高而减弱,通过改变KSL的值可以模 拟出这一效果
6.ADSR包络
首先说一下什么是ADSR包络.
ADSR是Attack,Decay,Sustain,Release的首字母缩写.通常用在电子音乐乐器的声音设计上.通过调整这四个值可以调制出与真实乐器十分接近的声音.
如上图所示,我们可以把ADSR四个参数看成关于时间t的分段函数.
$$
Volume(t) = \begin{cases} Attack(t)\ Decay(t)\Sustain(t)\Release(t)\end{cases}
$$
通过改变这四个函数来控制响度随时间改变模拟出不同的乐器.下图是真实钢琴发出的声音,我们可以很容易看出它的ADSR包络走向:
在YM3812中,ADSR被分为两个寄存器来控制.
1):Attack/Decay($60~$
75)
2):Sustain/Release($80~95)
7.Block/F-number
1):F-Number($Ax),($
Bx):
通过改变F-Number的值我们可以得到我们想要的音高.
2):Block:控制音阶的八度关系.
3):Key_ON:置1时产生信号,置0时停止产生信号.
那到底如何得到想要的频率呢?
有如下公式:
$ fmus = fsamF2^b-1 2^{19}$
$fsam = {fM \over 72}$
fmus:所需频率
fsam:采样频率
F:F-number值
b:block值
fM:主时钟频率
7.Feedback/Connection($C0~$
C8)
1):Connection:控制运算子的链接方式.在YM3812中有两种链接方式:
2):Feedback:调制因数
8.AM VIB-Depth/Rhythm($BD)
1):Rhythm:置1时,启用节奏乐器
此时,占用7-9通道来产生声音,而D0~D4对应位置1可以使对应乐器发声.但是7,8,9通道的KON位必须置1,否则不能发声
注:麻烦的是,节奏乐器的ADSR包络也得自己调.....
2):VIB-Depth:控制低频振荡器颤音深度,置1时为14音分,置0时为7音分.
3):AM-Depth:控制低频振荡器振幅.置1时为4.8dB,置0时为1dB.
8.波形选择($E0 ~ $
F5)
之前说FM调制时通过正弦波来调制,但其实任意波形都可.YM3812内置了四种波形供使用者使用:
芯片介绍部分结束,其中既有手册中的内容也有编者按照自己的理解加入的内容,其中可能有很多错误,希望读者们能多多指出.(之后还有三篇后续要写(超级大坑).