Example #1
0
        public void Init(byte[] instrData)
        {
            if (_ready)
            {
                Reset();
                return;
            }

            var pos = 0;

            if (instrData != null)
            {
                for (int i = 0; i < 6; i++)
                {
                    _rhChan[i].data       = instrData;
                    _rhChan[i].dataOffset = instrData.ToUInt16BigEndian(pos);
                    pos            += 2;
                    _rhChan[i].size = instrData.ToUInt16BigEndian(pos);
                    pos            += 2;
                }
                Reset();
                _ready = true;
            }
            else
            {
                for (int i = 0; i < 6; i++)
                {
                    _rhChan[i] = new RhtChannel();
                }
                _ready = false;
            }
        }
Example #2
0
        public void NextTick(int[] buffer, int offset, int bufferSize)
        {
            if (!_ready)
            {
                return;
            }

            for (var i = 0; i < bufferSize; i++)
            {
                _timer += _tickLength;
                while (_timer > _rtt)
                {
                    _timer -= _rtt;

                    for (int ii = 0; ii < 6; ii++)
                    {
                        RhtChannel s = _rhChan[ii];
                        if (s.active)
                        {
                            RecalcOuput(s);
                            if (s.decStep != 0)
                            {
                                AdvanceInput(s);
                                if (s.posOffset == s.endOffset)
                                {
                                    s.active = false;
                                }
                            }
                            s.decStep ^= 1;
                        }
                    }
                }

                int finOut = 0;

                for (int ii = 0; ii < 6; ii++)
                {
                    if (_rhChan[ii].active)
                    {
                        finOut += _rhChan[ii].@out;
                    }
                }

                finOut <<= 1;

                if ((1 & _volMaskA) != 0)
                {
                    finOut = (finOut * _volumeA) / Mixer.MaxMixerVolume;
                }

                if ((1 & _volMaskB) != 0)
                {
                    finOut = (finOut * _volumeB) / Mixer.MaxMixerVolume;
                }

                buffer[offset + (i << 1)]     += finOut;
                buffer[offset + (i << 1) + 1] += finOut;
            }
        }
Example #3
0
        void RecalcOuput(RhtChannel ins)
        {
            int s = _totalLevel + ins.level;
            int x = s > 62 ? 0 : (1 + (s >> 3));
            int y = s > 62 ? 0 : (15 - (s & 7));

            ins.@out = ((ins.samples[ins.decStep] * y) >> x) & ~3;
        }
Example #4
0
        void AdvanceInput(RhtChannel ins)
        {
            sbyte cur = (sbyte)ins.data[ins.posOffset++];

            for (int i = 0; i < 2; i++)
            {
                int b = (2 * (cur & 7) + 1) * stepTable[ins.decState] / 8;
                ins.samples[i] = (short)ScummHelper.Clip(ins.samples[i ^ 1] + ((cur & 8) != 0 ? b : -b), -2048, 2047);
                ins.decState   = (sbyte)ScummHelper.Clip(ins.decState + adjustIndex[cur & 7], 0, 48);
                cur          >>= 4;
            }
        }
Example #5
0
        public void WriteReg(byte address, byte value)
        {
            if (!_ready)
            {
                return;
            }

            byte h = (byte)(address >> 4);
            byte l = (byte)(address & 15);

            if (address > 15)
            {
                _reg[address](value);
            }

            if (address == 0)
            {
                if ((value & 0x80) != 0)
                {
                    //key off
                    for (int i = 0; i < 6; i++)
                    {
                        if (((value >> i) & 1) != 0)
                        {
                            _rhChan[i].active = false;
                        }
                    }
                }
                else
                {
                    //key on
                    for (int i = 0; i < 6; i++)
                    {
                        if (((value >> i) & 1) != 0)
                        {
                            RhtChannel s = _rhChan[i];
                            s.posOffset  = s.startOffset;
                            s.active     = true;
                            s.@out       = 0;
                            s.samples[0] = s.samples[1] = 0;
                            s.decStep    = 1;
                            s.decState   = 0;
                        }
                    }
                }
            }
            else if (address == 1)
            {
                // total level
                _totalLevel = (byte)((value & 63) ^ 63);
                for (int i = 0; i < 6; i++)
                {
                    RecalcOuput(_rhChan[i]);
                }
            }
            else if (h == 0 && ((l & 8) != 0))
            {
                // instrument level
                l &= 7;
                _rhChan[l].level = (byte)((value & 0x1f) ^ 0x1f);
                RecalcOuput(_rhChan[l]);
            }
            else if ((h & 3) != 0)
            {
                l &= 7;
                if (h == 1)
                {
                    // set start offset
                    _rhChan[l].startOffset = _rhChan[l].dataOffset + ((_rhChan[l].startPosH << 8 | _rhChan[l].startPosL) << 8);
                }
                else if (h == 2)
                {
                    // set end offset
                    _rhChan[l].endOffset = _rhChan[l].dataOffset + ((_rhChan[l].endPosH << 8 | _rhChan[l].endPosL) << 8) + 255;
                }
            }
        }
        public void Init(byte[] instrData)
        {
            if (_ready)
            {
                Reset();
                return;
            }

            var pos = 0;

            if (instrData != null)
            {
                for (int i = 0; i < 6; i++)
                {
                    _rhChan[i].data = instrData;
                    _rhChan[i].dataOffset = instrData.ToUInt16BigEndian(pos);
                    pos += 2;
                    _rhChan[i].size = instrData.ToUInt16BigEndian(pos);
                    pos += 2;
                }
                Reset();
                _ready = true;
            }
            else
            {
                for (int i = 0; i < 6; i++)
                {
                    _rhChan[i] = new RhtChannel();
                }
                _ready = false;
            }
        }
        void AdvanceInput(RhtChannel ins)
        {
            sbyte cur = (sbyte)ins.data[ins.posOffset++];

            for (int i = 0; i < 2; i++)
            {
                int b = (2 * (cur & 7) + 1) * stepTable[ins.decState] / 8;
                ins.samples[i] = (short)ScummHelper.Clip(ins.samples[i ^ 1] + ((cur & 8) != 0 ? b : -b), -2048, 2047);
                ins.decState = (sbyte)ScummHelper.Clip(ins.decState + adjustIndex[cur & 7], 0, 48);
                cur >>= 4;
            }
        }
 void RecalcOuput(RhtChannel ins)
 {
     int s = _totalLevel + ins.level;
     int x = s > 62 ? 0 : (1 + (s >> 3));
     int y = s > 62 ? 0 : (15 - (s & 7));
     ins.@out = ((ins.samples[ins.decStep] * y) >> x) & ~3;
 }