コード例 #1
0
        public static IIMuse Create(MidiDriver nativeMidiDriver, MidiDriver adlibMidiDriver)
        {
            var imuse = new IMuseInternal();

            imuse.Initialize(nativeMidiDriver, adlibMidiDriver);
            return(imuse);
        }
コード例 #2
0
        public void Do(Player player, byte[] msg, ushort len)
        {
            IMuseInternal se = player._se;

            switch (msg[0])
            {
            case 0:
                // Trigger Event
                // Triggers are set by doCommand(ImSetTrigger).
                // When a SysEx marker is encountered whose sound
                // ID and marker ID match what was set by ImSetTrigger,
                // something magical is supposed to happen....
                for (var a = 0; a < se._snm_triggers.Length; ++a)
                {
                    if (se._snm_triggers[a].Sound == player.Id &&
                        se._snm_triggers[a].Id == msg[1])
                    {
                        se._snm_triggers[a].Sound = se._snm_triggers[a].Id = 0;
                        se.DoCommand(8, se._snm_triggers[a].Command);
                        break;
                    }
                }
                break;

            case 1:
                // maybe_jump.
                if (player.Scanning)
                {
                    break;
                }
                using (var br = new BinaryReader(new MemoryStream(msg)))
                {
                    br.ReadByte();

                    player.MaybeJump(br.ReadByte(), (uint)(br.ReadByte() - 1), (uint)((br.ReadUInt16BigEndian() - 1) * 4 + br.ReadByte()),
                                     (uint)((br.ReadByte() * TicksPerBeat) >> 2) + br.ReadByte());
                }
                break;

            default:
                scummSysEx.Do(player, msg, len);
                break;
            }
        }
コード例 #3
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;
            }
        }