void McIncStuff(AdLibVoice voice, Struct10 s10, Struct11 s11) { byte code; AdLibPart part = voice.Part; code = Struct10OnTimer(s10, s11); if ((code & 1) != 0) { switch (s11.Param) { case 0: voice.Vol2 = (byte)(s10.StartValue + s11.ModifyVal); if (!_scummSmallHeader) { AdlibSetParam(voice.Channel, 0, volumeTable[volumeLookupTable[voice.Vol2, part._volEff >> 2]]); } else { AdlibSetParam(voice.Channel, 0, voice.Vol2); } break; case 13: voice.Vol1 = (byte)(s10.StartValue + s11.ModifyVal); if (voice.TwoChan != 0 && !_scummSmallHeader) { AdlibSetParam(voice.Channel, 13, volumeTable[volumeLookupTable[voice.Vol1, part._volEff >> 2]]); } else { AdlibSetParam(voice.Channel, 13, voice.Vol1); } break; case 30: s11.S10.ModWheel = (sbyte)s11.ModifyVal; break; case 31: s11.S10.Unk3 = (sbyte)s11.ModifyVal; break; default: AdlibSetParam(voice.Channel, s11.Param, s10.StartValue + s11.ModifyVal); break; } } if ((code & 2) != 0 && s11.Flag0x10 != 0) AdlibKeyOnOff(voice.Channel); }
void McOff(AdLibVoice voice) { AdlibKeyOff(voice.Channel); var tmp = voice.Prev; if (voice.Next != null) voice.Next.Prev = tmp; if (tmp != null) tmp.Next = voice.Next; else voice.Part._voice = voice.Next; voice.Part = null; }
void LinkMc(AdLibPart part, AdLibVoice voice) { voice.Part = part; voice.Next = part._voice; part._voice = voice; voice.Prev = null; if (voice.Next != null) voice.Next.Prev = voice; }
void McInitStuff(AdLibVoice voice, Struct10 s10, Struct11 s11, byte flags, InstrumentExtra ie) { var part = voice.Part; s11.ModifyVal = 0; s11.Flag0x40 = (byte)(flags & 0x40); s10.Loop = (byte)(flags & 0x20); s11.Flag0x10 = (byte)(flags & 0x10); s11.Param = paramTable1[flags & 0xF]; s10.MaxValue = maxValTable[flags & 0xF]; s10.Unk3 = 31; if (s11.Flag0x40 != 0) { s10.ModWheel = (sbyte)(part._modWheel >> 2); } else { s10.ModWheel = 31; } switch (s11.Param) { case 0: s10.StartValue = voice.Vol2; break; case 13: s10.StartValue = voice.Vol1; break; case 30: s10.StartValue = 31; s11.S10.ModWheel = 0; break; case 31: s10.StartValue = 0; s11.S10.Unk3 = 0; break; default: s10.StartValue = (short)AdlibGetRegValueParam(voice.Channel, s11.Param); break; } Struct10Init(s10, ie); }
void McKeyOn(AdLibVoice voice, AdLibInstrument instr, byte note, byte velocity, AdLibInstrument second, byte pan) { AdLibPart part = voice.Part; byte vol1, vol2; #if ENABLE_OPL3 byte secVol1 = 0, secVol2 = 0; #endif voice.TwoChan = (byte)(instr.Feedback & 1); voice.Note = note; voice.WaitForPedal = false; voice.Duration = instr.Duration; if (voice.Duration != 0) voice.Duration *= 63; if (!_scummSmallHeader) { #if ENABLE_OPL3 if (_opl3Mode) vol1 = (instr.modScalingOutputLevel & 0x3F) + (velocity * ((instr.modWaveformSelect >> 3) + 1)) / 64; else #endif vol1 = (byte)((instr.ModScalingOutputLevel & 0x3F) + volumeLookupTable[velocity >> 1, instr.ModWaveformSelect >> 2]); } else { vol1 = (byte)(0x3f - (instr.ModScalingOutputLevel & 0x3F)); } if (vol1 > 0x3F) vol1 = 0x3F; voice.Vol1 = vol1; if (!_scummSmallHeader) { #if ENABLE_OPL3 if (_opl3Mode) vol2 = (instr.carScalingOutputLevel & 0x3F) + (velocity * ((instr.carWaveformSelect >> 3) + 1)) / 64; else #endif vol2 = (byte)((instr.CarScalingOutputLevel & 0x3F) + volumeLookupTable[velocity >> 1, instr.CarWaveformSelect >> 2]); } else { vol2 = (byte)(0x3f - (instr.CarScalingOutputLevel & 0x3F)); } if (vol2 > 0x3F) vol2 = 0x3F; voice.Vol2 = vol2; #if ENABLE_OPL3 if (_opl3Mode) { voice._secTwoChan = second.feedback & 1; secVol1 = (second.modScalingOutputLevel & 0x3F) + (velocity * ((second.modWaveformSelect >> 3) + 1)) / 64; if (secVol1 > 0x3F) { secVol1 = 0x3F; } voice._secVol1 = secVol1; secVol2 = (second.carScalingOutputLevel & 0x3F) + (velocity * ((second.carWaveformSelect >> 3) + 1)) / 64; if (secVol2 > 0x3F) { secVol2 = 0x3F; } voice._secVol2 = secVol2; } #endif if (!_scummSmallHeader) { #if ENABLE_OPL3 if (!_opl3Mode) { #endif int c = part._volEff >> 2; vol2 = volumeTable[volumeLookupTable[vol2, c]]; if (voice.TwoChan != 0) vol1 = volumeTable[volumeLookupTable[vol1, c]]; #if ENABLE_OPL3 } else { vol2 = g_volumeTable[((vol2 + 1) * part._volEff) >> 7]; secVol2 = g_volumeTable[((secVol2 + 1) * part._volEff) >> 7]; if (voice._twoChan) vol1 = g_volumeTable[((vol1 + 1) * part._volEff) >> 7]; if (voice._secTwoChan) secVol1 = g_volumeTable[((secVol1 + 1) * part._volEff) >> 7]; } #endif } AdlibSetupChannel(voice.Channel, instr, vol1, vol2); #if ENABLE_OPL3 if (!_opl3Mode) { #endif AdlibNoteOnEx(voice.Channel, /*part._transposeEff + */note, part._detuneEff + (part._pitchBend * part._pitchBendFactor >> 6)); if ((instr.FlagsA & 0x80) != 0) { McInitStuff(voice, voice.S10a, voice.S11a, instr.FlagsA, instr.ExtraA); } else { voice.S10a.Active = 0; } if ((instr.FlagsB & 0x80) != 0) { McInitStuff(voice, voice.S10b, voice.S11b, instr.FlagsB, instr.ExtraB); } else { voice.S10b.Active = 0; } #if ENABLE_OPL3 } else { adlibSetupChannelSecondary(voice._channel, second, secVol1, secVol2, pan); adlibNoteOnEx(voice._channel, note, part._pitchBend >> 1); } #endif }
public AdlibMidiDriver(IMixer mixer) : base(mixer) { _voiceIndex = -1; _parts = new AdLibPart[32]; for (var i = 0; i < _parts.Length; ++i) { _parts[i] = new AdLibPart(); _parts[i].Init(this, (byte)(i + ((i >= 9) ? 1 : 0))); } _percussion = new AdLibPercussionChannel(); _percussion.Init(this, 9); _timerIncrease = 0xD69; _timerThreshold = 0x411B; _voices = new AdLibVoice[9]; for (int i = 0; i < _voices.Length; i++) { _voices[i] = new AdLibVoice(); } }