返回
{***************************************************************}
{*** FVision Unit Version1.0 ***}
{*** 蓝蚂蚁工作室 ***}
{***************************************************************}
{*** FM乐器单元 ***}
{***************************************************************}
{$F+,O+,X+,S-,D-}
Unit FSbFm;
Interface
Uses
FDsp;
Type
FM_Instrument=record
SoundCharacteristic:Array[0..1] of Byte;
Level:Array[0..1] of Byte; {衰减率}
AttackDecay:Array[0..1] of Byte; {上升率,下降率}
SustainRelease:Array[0..1] of Byte;
WaveSelect:Array[0..1] of Byte; {波形选择}
Feedback:Byte; {反馈联结}
Filler:Array[0..4] of Byte;
end;
Procedure WriteFM(Chip,Addr:Byte;Data:Byte);
Procedure FMReset;
Procedure FMKeyOff(Voice:Integer);
Procedure FMKeyOn(Voice,Freq,Octave:Integer);
Procedure FMVoiceVolume(Voice,Vol:Integer);
Procedure FMSetVoice(Voice_Num:Integer;FM_Ins:FM_Instrument);
Implementation
Procedure WriteFM(Chip,Addr:Byte;Data:Byte);
var
Temp:Byte;
begin
Port[DspBasePort+8]:=Addr;
Temp:=Port[DspBasePort+8];
Port[DspBasePort+9]:=Data;
Temp:=Port[DspBasePort+8];
Temp:=Port[DspBasePort+8];
Temp:=Port[DspBasePort+8];
Temp:=Port[DspBasePort+8];
end;
Procedure FMReset;
begin
WriteFM(0,1,0);
WriteFM(1,1,0);
end;
Procedure FMKeyOff(Voice:Integer);
begin
WriteFM(Voice div 11,$B0+Voice mod 11,0);
end;
Procedure FMKeyOn(Voice,Freq,Octave:Integer);
begin
WriteFM(Voice div 11,$A0+Voice mod 11,Freq and $FF);
WriteFM(Voice div 11,$B0+Voice mod 11,(Freq shr 8) or (Octave shl 2) or $20);
end;
Procedure FMVoiceVolume(Voice,Vol:Integer);
begin
WriteFM(Voice div 11,$40+Voice mod 11,Vol);
end;
Procedure FMSetVoice(Voice_Num:Integer;FM_Ins:FM_Instrument);
var
Chip,Cell_Offset,Op_Cell_Num:Integer;
begin
Chip:=Voice_Num div 11;
Voice_Num:=Voice_Num mod 11;
Cell_Offset:=Voice_Num mod 3 + ((Voice_Num div 3) shl 3);
Op_Cell_Num:=$20+Cell_Offset;
WriteFM(Chip,Op_Cell_Num,FM_Ins.SoundCharacteristic[0]);
Inc(Op_Cell_Num,3);
WriteFM(Chip,Op_Cell_Num,FM_Ins.SoundCharacteristic[1]);
Op_Cell_Num:=$40+Cell_Offset;
WriteFM(Chip,Op_Cell_Num,FM_Ins.Level[0]);
Inc(Op_Cell_Num,3);
WriteFM(Chip,Op_Cell_Num,FM_Ins.Level[1]);
Op_Cell_Num:=$60+Cell_Offset;
WriteFM(Chip,Op_Cell_Num,FM_Ins.AttackDecay[0]);
Inc(Op_Cell_Num,3);
WriteFM(Chip,Op_Cell_Num,FM_Ins.AttackDecay[1]);
Op_Cell_Num:=$80+Cell_Offset;
WriteFM(Chip,Op_Cell_Num,FM_Ins.SustainRelease[0]);
Inc(Op_Cell_Num,3);
WriteFM(Chip,Op_Cell_Num,FM_Ins.SustainRelease[1]);
Op_Cell_Num:=$E0+Cell_Offset;
WriteFM(Chip,Op_Cell_Num,FM_Ins.WaveSelect[0]);
Inc(Op_Cell_Num,3);
WriteFM(Chip,Op_Cell_Num,FM_Ins.WaveSelect[0]);
Op_Cell_Num:=$C0+Voice_Num;
WriteFM(Chip,Op_Cell_Num,FM_Ins.Feedback);
end;
end.