示例#1
0
        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;
        }
示例#2
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);
        }
示例#3
0
 void ControlModulationWheel(byte value)
 {
     _modWheel = (sbyte)value;
     for (TownsMidiOutputChannel oc = _out; oc != null; oc = oc._next)
     {
         oc.SetModWheel(value);
     }
 }
示例#4
0
 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);
     }
 }
示例#5
0
 void ReleasePedal()
 {
     for (TownsMidiOutputChannel oc = _out; oc != null; oc = oc._next)
     {
         if (oc._sustainNoteOff != 0)
         {
             oc.Disconnect();
         }
     }
 }
示例#6
0
        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;
            }
        }
示例#7
0
        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;
            }
        }
示例#8
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();
                }
            }
        }