GetPart() public method

public GetPart ( byte chan ) : Part
chan byte
return Part
コード例 #1
0
ファイル: ScummSysEx.cs プロジェクト: scemino/nscumm
        public void Do(Player player, byte[] msg, ushort len)
        {
            IMuseInternal se = player._se;
            int p = 0;

            byte code;
            switch (code = msg[p++])
            {
                case 0:
                    {
                        // Allocate new part.
                        // There are 8 bytes (after decoding!) of useful information here.
                        // Here is what we know about them so far:
                        //   BYTE 0: Channel #
                        //   BYTE 1: BIT 01(0x01): Part on?(1 = yes)
                        //            BIT 02(0x02): Reverb? (1 = yes) [bug #1088045]
                        //   BYTE 2: Priority adjustment
                        //   BYTE 3: Volume [guessing]
                        //   BYTE 4: Pan [bug #1088045]
                        //   BYTE 5: BIT 8(0x80): Percussion?(1 = yes) [guessed?]
                        //   BYTE 5: Transpose, if set to 0x80(=-1) it means no transpose
                        //   BYTE 6: Detune
                        //   BYTE 7: Pitchbend factor [bug #1088045]
                        //   BYTE 8: Program
                        var part = player.GetPart((byte)(msg[p] & 0x0F));
                        var buf = DecodeSysExBytes(msg, p + 1, len - 1);
                        if (part != null)
                        {
                            part.SetOnOff((buf[0] & 0x01) != 0);
                            part.EffectLevel((byte)(((buf[0] & 0x02) != 0) ? 127 : 0));
                            part.Priority = (sbyte)buf[1];
                            part.Volume = buf[2];
                            part.Pan = buf[3];
                            part.Percussion = player.SupportsPercussion && ((buf[4] & 0x80) > 0);
                            part.SetTranspose((sbyte)buf[4]);
                            part.Detune = buf[5];
                            part.PitchBendFactor(buf[6]);
                            if (part.Percussion)
                            {
                                if (part.MidiChannel != null)
                                {
                                    part.Off();
                                    se.ReallocateMidiChannels(player.MidiDriver);
                                }
                            }
                            else
                            {
                                if (player.IsMIDI)
                                {
                                    // Even in cases where a program does not seem to be specified,
                                    // i.e. bytes 15 and 16 are 0, we send a program change because
                                    // 0 is a valid program number. MI2 tests show that in such
                                    // cases, a regular program change message always seems to follow
                                    // anyway.
                                    part.Instrument.Program(buf[7], player.IsMT32);
                                }
                                else
                                {
                                    // Like the original we set up the instrument data of the
                                    // specified program here too. In case the global
                                    // instrument data is not loaded already, this will take
                                    // care of setting a default instrument too.
                                    se.CopyGlobalInstrument(buf[7], part.Instrument);
                                }
                                part.SendAll();
                            }
                        }
                    }
                    break;

                case 1:
                        // Shut down a part. [Bug 1088045, comments]
                    {
                        var part = player.GetPart(msg[p]);
                        if (part != null)
                            part.Uninit();
                    }
                    break;

                case 2: // Start of song. Ignore for now.
                    break;

                case 16: // AdLib instrument definition(Part)
                    {
                        var a = (byte)(msg[p++] & 0x0F);
                        ++p; // Skip hardware type
                        var part = player.GetPart(a);
                        if (part != null)
                        {
                            if (len == 62 || len == 48)
                            {
                                var buf = DecodeSysExBytes(msg, p, len - 2);
                                part.SetInstrument(buf);
                            }
                            else
                            {
                                part.ProgramChange(254); // Must be invalid, but not 255 (which is reserved)
                            }
                        }
                    }
                    break;

                case 17: // AdLib instrument definition(Global)
                    {
                        p += 2; // Skip hardware type and... whatever came right before it
                        var a = msg[p++];
                        var buf = DecodeSysExBytes(msg, p, len - 3);
                        if (len == 63 || len == 49)
                            se.SetGlobalInstrument(a, buf);
                    }
                    break;

                case 33: // Parameter adjust
                    {
                        var a = msg[p++] & 0x0F;
                        ++p; // Skip hardware type
                        var buf = DecodeSysExBytes(msg, p, len - 2);
                        var part = player.GetPart((byte)a);
                        if (part != null)
                        {
                            using (var br = new BinaryReader(new MemoryStream(buf)))
                            {
                                part.SetParam((byte)br.ReadUInt16BigEndian(), (int)br.ReadUInt16BigEndian());
                            }
                        }
                    }
                    break;

                case 48: // Hook - jump
                    {
                        if (player.Scanning)
                            break;
                        var buf = DecodeSysExBytes(msg, p + 1, len - 1);
                        using (var br = new BinaryReader(new MemoryStream(buf)))
                        {
                            player.MaybeJump(br.ReadByte(), br.ReadUInt16BigEndian(), br.ReadUInt16BigEndian(), br.ReadUInt16BigEndian());
                        }
                    }
                    break;

                case 49: // Hook - global transpose
                    {
                        var buf = DecodeSysExBytes(msg, p + 1, len - 1);
                        player.MaybeSetTranspose(buf);
                    }
                    break;

                case 50: // Hook - part on/off
                    {
                        var tmp = msg[p++] & 0x0F;
                        var buf = DecodeSysExBytes(msg, p, len - 1, 1);
                        buf[0] = (byte)tmp;
                        player.MaybePartOnOff(buf);
                    }
                    break;

                case 51: // Hook - set volume
                    {
                        var tmp = msg[p++] & 0x0F;
                        var buf = DecodeSysExBytes(msg, p, len - 1, 1);
                        buf[0] = (byte)tmp;
                        player.MaybeSetVolume(buf);
                    }
                    break;

                case 52: // Hook - set program
                    {
                        var tmp = msg[p++] & 0x0F;
                        var buf = DecodeSysExBytes(msg, p, len - 1, 1);
                        buf[0] = (byte)tmp;
                        player.MaybeSetProgram(buf);
                    }
                    break;

                case 53: // Hook - set transpose
                    {
                        var tmp = msg[p++] & 0x0F;
                        var buf = DecodeSysExBytes(msg, p, len - 1, 1);
                        buf[0] = (byte)tmp;
                        player.MaybeSetTransposePart(buf);
                    }
                    break;

                case 64: // Marker
                    p++;
                    len--;
                    while (len-- != 0)
                    {
                        se.HandleMarker(player.Id, msg[p++]);
                    }
                    break;

                case 80: // Loop
                    {
                        var buf = DecodeSysExBytes(msg, p + 1, len - 1);
                        using (var br = new BinaryReader(new MemoryStream(buf)))
                        {
                            player.SetLoop(br.ReadUInt16BigEndian(), br.ReadUInt16BigEndian(),
                                br.ReadUInt16BigEndian(), br.ReadUInt16BigEndian(),
                                br.ReadUInt16BigEndian());
                        }
                    }
                    break;

                case 81: // End loop
                    player.ClearLoop();
                    break;

                case 96: // Set instrument
                    {
                        var part = player.GetPart((byte)(msg[p] & 0x0F));
                        var a = (msg[p + 1] & 0x0F) << 12 | (msg[p + 2] & 0x0F) << 8 | (msg[p + 3] & 0x0F) << 4 | (msg[p + 4] & 0x0F);
                        if (part != null)
                            part.SetInstrument((uint)a);
                    }
                    break;

                default:
                    Debug.WriteLine("Unknown SysEx command {0}", (int)code);
                    break;
            }
        }
コード例 #2
0
        public void Do(Player player, byte[] msg, ushort len)
        {
            IMuseInternal se = player._se;
            int           p  = 0;

            byte code;

            switch (code = msg[p++])
            {
            case 0:
            {
                // Allocate new part.
                // There are 8 bytes (after decoding!) of useful information here.
                // Here is what we know about them so far:
                //   BYTE 0: Channel #
                //   BYTE 1: BIT 01(0x01): Part on?(1 = yes)
                //            BIT 02(0x02): Reverb? (1 = yes) [bug #1088045]
                //   BYTE 2: Priority adjustment
                //   BYTE 3: Volume [guessing]
                //   BYTE 4: Pan [bug #1088045]
                //   BYTE 5: BIT 8(0x80): Percussion?(1 = yes) [guessed?]
                //   BYTE 5: Transpose, if set to 0x80(=-1) it means no transpose
                //   BYTE 6: Detune
                //   BYTE 7: Pitchbend factor [bug #1088045]
                //   BYTE 8: Program
                var part = player.GetPart((byte)(msg[p] & 0x0F));
                var buf  = DecodeSysExBytes(msg, p + 1, len - 1);
                if (part != null)
                {
                    part.SetOnOff((buf[0] & 0x01) != 0);
                    part.EffectLevel((byte)(((buf[0] & 0x02) != 0) ? 127 : 0));
                    part.Priority   = (sbyte)buf[1];
                    part.Volume     = buf[2];
                    part.Pan        = buf[3];
                    part.Percussion = player.SupportsPercussion && ((buf[4] & 0x80) > 0);
                    part.SetTranspose((sbyte)buf[4]);
                    part.Detune = buf[5];
                    part.PitchBendFactor(buf[6]);
                    if (part.Percussion)
                    {
                        if (part.MidiChannel != null)
                        {
                            part.Off();
                            se.ReallocateMidiChannels(player.MidiDriver);
                        }
                    }
                    else
                    {
                        if (player.IsMIDI)
                        {
                            // Even in cases where a program does not seem to be specified,
                            // i.e. bytes 15 and 16 are 0, we send a program change because
                            // 0 is a valid program number. MI2 tests show that in such
                            // cases, a regular program change message always seems to follow
                            // anyway.
                            part.Instrument.Program(buf[7], player.IsMT32);
                        }
                        else
                        {
                            // Like the original we set up the instrument data of the
                            // specified program here too. In case the global
                            // instrument data is not loaded already, this will take
                            // care of setting a default instrument too.
                            se.CopyGlobalInstrument(buf[7], part.Instrument);
                        }
                        part.SendAll();
                    }
                }
            }
            break;

            case 1:
                // Shut down a part. [Bug 1088045, comments]
            {
                var part = player.GetPart(msg[p]);
                if (part != null)
                {
                    part.Uninit();
                }
            }
            break;

            case 2:     // Start of song. Ignore for now.
                break;

            case 16:     // AdLib instrument definition(Part)
            {
                var a = (byte)(msg[p++] & 0x0F);
                ++p;         // Skip hardware type
                var part = player.GetPart(a);
                if (part != null)
                {
                    if (len == 62 || len == 48)
                    {
                        var buf = DecodeSysExBytes(msg, p, len - 2);
                        part.SetInstrument(buf);
                    }
                    else
                    {
                        part.ProgramChange(254);         // Must be invalid, but not 255 (which is reserved)
                    }
                }
            }
            break;

            case 17:     // AdLib instrument definition(Global)
            {
                p += 2;  // Skip hardware type and... whatever came right before it
                var a   = msg[p++];
                var buf = DecodeSysExBytes(msg, p, len - 3);
                if (len == 63 || len == 49)
                {
                    se.SetGlobalInstrument(a, buf);
                }
            }
            break;

            case 33:     // Parameter adjust
            {
                var a = msg[p++] & 0x0F;
                ++p;         // Skip hardware type
                var buf  = DecodeSysExBytes(msg, p, len - 2);
                var part = player.GetPart((byte)a);
                if (part != null)
                {
                    using (var br = new BinaryReader(new MemoryStream(buf)))
                    {
                        part.SetParam((byte)br.ReadUInt16BigEndian(), (int)br.ReadUInt16BigEndian());
                    }
                }
            }
            break;

            case 48:     // Hook - jump
            {
                if (player.Scanning)
                {
                    break;
                }
                var buf = DecodeSysExBytes(msg, p + 1, len - 1);
                using (var br = new BinaryReader(new MemoryStream(buf)))
                {
                    player.MaybeJump(br.ReadByte(), br.ReadUInt16BigEndian(), br.ReadUInt16BigEndian(), br.ReadUInt16BigEndian());
                }
            }
            break;

            case 49:     // Hook - global transpose
            {
                var buf = DecodeSysExBytes(msg, p + 1, len - 1);
                player.MaybeSetTranspose(buf);
            }
            break;

            case 50:     // Hook - part on/off
            {
                var tmp = msg[p++] & 0x0F;
                var buf = DecodeSysExBytes(msg, p, len - 1, 1);
                buf[0] = (byte)tmp;
                player.MaybePartOnOff(buf);
            }
            break;

            case 51:     // Hook - set volume
            {
                var tmp = msg[p++] & 0x0F;
                var buf = DecodeSysExBytes(msg, p, len - 1, 1);
                buf[0] = (byte)tmp;
                player.MaybeSetVolume(buf);
            }
            break;

            case 52:     // Hook - set program
            {
                var tmp = msg[p++] & 0x0F;
                var buf = DecodeSysExBytes(msg, p, len - 1, 1);
                buf[0] = (byte)tmp;
                player.MaybeSetProgram(buf);
            }
            break;

            case 53:     // Hook - set transpose
            {
                var tmp = msg[p++] & 0x0F;
                var buf = DecodeSysExBytes(msg, p, len - 1, 1);
                buf[0] = (byte)tmp;
                player.MaybeSetTransposePart(buf);
            }
            break;

            case 64:     // Marker
                p++;
                len--;
                while (len-- != 0)
                {
                    se.HandleMarker(player.Id, msg[p++]);
                }
                break;

            case 80:     // Loop
            {
                var buf = DecodeSysExBytes(msg, p + 1, len - 1);
                using (var br = new BinaryReader(new MemoryStream(buf)))
                {
                    player.SetLoop(br.ReadUInt16BigEndian(), br.ReadUInt16BigEndian(),
                                   br.ReadUInt16BigEndian(), br.ReadUInt16BigEndian(),
                                   br.ReadUInt16BigEndian());
                }
            }
            break;

            case 81:     // End loop
                player.ClearLoop();
                break;

            case 96:     // Set instrument
            {
                var part = player.GetPart((byte)(msg[p] & 0x0F));
                var a    = (msg[p + 1] & 0x0F) << 12 | (msg[p + 2] & 0x0F) << 8 | (msg[p + 3] & 0x0F) << 4 | (msg[p + 4] & 0x0F);
                if (part != null)
                {
                    part.SetInstrument((uint)a);
                }
            }
            break;

            default:
                Debug.WriteLine("Unknown SysEx command {0}", (int)code);
                break;
            }
        }