public MidiDriver_TOWNS(IMixer mixer) { _baseTempo = 10080; _rand = 1; // We set exteral mutex handling to true to avoid lockups in SCUMM which has its own mutex. _intf = new TownsAudioInterface(mixer, this, true); _channels = new TownsMidiInputChannel[32]; for (int i = 0; i < 32; i++) _channels[i] = new TownsMidiInputChannel(this, i > 8 ? (i + 1) : i); _out = new TownsMidiOutputChannel[6]; for (int i = 0; i < 6; i++) { _out[i] = new TownsMidiOutputChannel(this, i); } _chanState = new TownsMidiChanState[32]; for (int i = 0; i < _chanState.Length; i++) { _chanState[i] = new TownsMidiChanState(); } _operatorLevelTable = new byte[2048]; for (int i = 0; i < 64; i++) { for (int ii = 0; ii < 32; ii++) _operatorLevelTable[(i << 5) + ii] = (byte)(((i * (ii + 1)) >> 5) & 0xff); } for (int i = 0; i < 64; i++) _operatorLevelTable[i << 5] = 0; }
public TownsMidiOutputChannel AllocateOutputChannel(int pri) { TownsMidiOutputChannel res = null; for (int i = 0; i < 6; i++) { if (++_allocCurPos == 6) { _allocCurPos = 0; } var s = _out[_allocCurPos].CheckPriority(pri); if (s == (int)CheckPriorityStatus.Disconnected) { return(_out[_allocCurPos]); } if (s != (int)CheckPriorityStatus.HighPriority) { pri = (int)s; res = _out[_allocCurPos]; } } if (res != null) { res.Disconnect(); } return(res); }
void ControlModulationWheel(byte value) { _modWheel = (sbyte)value; for (TownsMidiOutputChannel oc = _out; oc != null; oc = oc._next) { oc.SetModWheel(value); } }
public override void PitchBendFactor(byte value) { _pitchBendFactor = value; _freqLSB = (ushort)(((_pitchBend * _pitchBendFactor) >> 6) + _detune); for (TownsMidiOutputChannel oc = _out; oc != null; oc = oc._next) { oc.NoteOnPitchBend((byte)(oc._note + oc._in._transpose), _freqLSB); } }
void ReleasePedal() { for (TownsMidiOutputChannel oc = _out; oc != null; oc = oc._next) { if (oc._sustainNoteOff != 0) { oc.Disconnect(); } } }
public override void NoteOn(byte note, byte velocity) { TownsMidiOutputChannel oc = _driver.AllocateOutputChannel(_priority); if (oc == null) { return; } oc.Connect(this); oc._adjustModTl = (byte)(_instrument[10] & 1); oc._note = note; oc._sustainNoteOff = 0; oc._duration = (short)(_instrument[29] * 63); oc._operator1Tl = (byte)((_instrument[1] & 0x3f) + _driver._operatorLevelTable[((velocity >> 1) << 5) + (_instrument[4] >> 2)]); if (oc._operator1Tl > 63) { oc._operator1Tl = 63; } oc._operator2Tl = (byte)((_instrument[6] & 0x3f) + _driver._operatorLevelTable[((velocity >> 1) << 5) + (_instrument[9] >> 2)]); if (oc._operator2Tl > 63) { oc._operator2Tl = 63; } oc.SetupProgram(_instrument, oc._adjustModTl == 1 ? _programAdjustLevel[_driver._operatorLevelTable[(_tl >> 2) + (oc._operator1Tl << 5)]] : oc._operator1Tl, _programAdjustLevel[_driver._operatorLevelTable[(_tl >> 2) + (oc._operator2Tl << 5)]]); oc.NoteOn((byte)(note + _transpose), _freqLSB); if ((_instrument[11] & 0x80) != 0) { oc.SetupEffects(0, _instrument[11], _instrument, 12); } else { oc._effectEnvelopes[0].state = EnvelopeState.Ready; } if ((_instrument[20] & 0x80) != 0) { oc.SetupEffects(1, _instrument[20], _instrument, 21); } else { oc._effectEnvelopes[1].state = EnvelopeState.Ready; } }
public MidiDriver_TOWNS(IMixer mixer) { _baseTempo = 10080; _rand = 1; // We set exteral mutex handling to true to avoid lockups in SCUMM which has its own mutex. _intf = new TownsAudioInterface(mixer, this, true); _channels = new TownsMidiInputChannel[32]; for (int i = 0; i < 32; i++) { _channels[i] = new TownsMidiInputChannel(this, i > 8 ? (i + 1) : i); } _out = new TownsMidiOutputChannel[6]; for (int i = 0; i < 6; i++) { _out[i] = new TownsMidiOutputChannel(this, i); } _chanState = new TownsMidiChanState[32]; for (int i = 0; i < _chanState.Length; i++) { _chanState[i] = new TownsMidiChanState(); } _operatorLevelTable = new byte[2048]; for (int i = 0; i < 64; i++) { for (int ii = 0; ii < 32; ii++) { _operatorLevelTable[(i << 5) + ii] = (byte)(((i * (ii + 1)) >> 5) & 0xff); } } for (int i = 0; i < 64; i++) { _operatorLevelTable[i << 5] = 0; } }
public override void NoteOff(byte note) { if (_out == null) { return; } for (TownsMidiOutputChannel oc = _out; oc != null; oc = oc._next) { if (oc._note != note) { continue; } if (_sustain != 0) { oc._sustainNoteOff = 1; } else { oc.Disconnect(); } } }