예제 #1
0
        /// <summary>
        /// Convert the sequence command to an MIDI one.
        /// </summary>
        /// <param name="c">The sequence command.</param>
        /// <param name="m">The out MIDI file.</param>
        /// <param name="t"></param>
        /// <param name="nextWaitAmount">Time to wait for the next command.</param>
        public static void SequenceCommand2MidiCommand(SequenceCommand c, MidiFile m, TrackChunk t, ref int nextWaitAmount)
        {
            //Switch type.
            switch ((CommandType)c.Identifier)
            {
            //Note.
            case CommandType commandType when(c.Identifier >= 0 && c.Identifier <= 0x7F):
                t.Events.Add(new NoteOnEvent(c.Identifier.To7Bit(), (c as NoteCommand).Velocity.To7Bit())
                {
                    DeltaTime = nextWaitAmount
                });

                t.Events.Add(new NoteOffEvent(c.Identifier.To7Bit(), (c as NoteCommand).Velocity.To7Bit())
                {
                    DeltaTime = Seq2MidTicks((c as NoteCommand).Length)
                });
                break;

            //Wait.
            case CommandType.Wait:
                nextWaitAmount = (int)(c as WaitCommand).Length;
                break;
            }

            //Wait time is now 0.
            if ((CommandType)c.Identifier != CommandType.Wait)
            {
                nextWaitAmount = 0;
            }
        }
예제 #2
0
        /// <summary>
        /// Read a sequence from a sequence file.
        /// </summary>
        /// <param name="seq">The sequence file.</param>
        public void FromSeqFile(string[] seq)
        {
            //New info.
            PrivateLabelOffsets = new List <int>();
            PublicLabelOffsets  = new Dictionary <string, int>();
            Commands            = new List <SequenceCommand>();

            //Temp private labels.
            Dictionary <string, int> privateLabels = new Dictionary <string, int>();

            //Commands with offsets.
            Dictionary <int, string> commandOffs = new Dictionary <int, string>();

            //Read each line.
            int commandNum = 0;

            foreach (string seqLine in seq)
            {
                //Remove comment area.
                string s = seqLine;
                if (seqLine.Contains(";"))
                {
                    s = seqLine.Split(';')[0];
                }

                //Remove spaces.
                s = s.Replace(" ", "").Replace("\t", "").Replace("\r", "");

                //The line is a label.
                if (s.EndsWith(":"))
                {
                    //Private label.
                    if (s.StartsWith("_"))
                    {
                        privateLabels.Add(s.Split(':')[0], commandNum);
                        PrivateLabelOffsets.Add(commandNum);
                    }

                    //Public label.
                    else
                    {
                        PublicLabelOffsets.Add(s.Split(':')[0], commandNum);
                    }
                }

                //Command is valid.
                else if (!s.Equals(""))
                {
                    SequenceCommand com = CommandFromString(s, commandNum, PrivateLabelOffsets, PublicLabelOffsets, commandOffs);
                    if (com != null)
                    {
                        Commands.Add(com);
                        commandNum++;
                    }
                }
            }
        }
예제 #3
0
 /// <summary>
 /// Remove null parameters from a command.
 /// </summary>
 /// <param name="c">The command.</param>
 public static void RemoveNullFromCommand(SequenceCommand c)
 {
     for (int i = 0; i < c.Parameters.Length; i++)
     {
         if (c.Parameters[i] == null)
         {
             c.Parameters[i] = (short)0;
         }
         else if (c.Parameters[i] as SequenceCommand != null)
         {
             RemoveNullFromCommand(c.Parameters[i] as SequenceCommand);
         }
     }
 }
예제 #4
0
        /// <summary>
        /// Read the sequence data.
        /// </summary>
        /// <param name="data">Sequence data.</param>
        /// <param name="byteOrder">Byte order.</param>
        public void Read(byte[] data, ByteOrder byteOrder)
        {
            //New reader.
            MemoryStream     src = new MemoryStream(data);
            BinaryDataReader br  = new BinaryDataReader(src)
            {
                ByteOrder = byteOrder
            };

            //Read the data.
            Commands = new List <SequenceCommand>();
            bool ended = false;

            while (br.Position < data.Length && !ended)
            {
                //Add command.
                var s = SequenceCommand.Read(br);
                Commands.Add(s);

                //If the command is end, and the rest is just padding.
                if (s as FinCommand != null)
                {
                    long   currPos = br.Position;
                    byte[] raw     = br.ReadBytes((int)(data.Length - currPos));
                    if (raw.Length > 0)
                    {
                        if (raw.Max() == 0)
                        {
                            ended = true;
                        }
                    }
                    else
                    {
                        ended = true;
                    }
                    br.Position = currPos;
                }
            }

            //Go ahead and convert the public offsets to command indices.
            for (int i = 0; i < PublicLabelOffsets.Count; i++)
            {
                //Convert the offset to an index.
                PublicLabelOffsets[PublicLabelOffsets.ElementAt(i).Key] = OffsetToCommandIndex(Commands, PublicLabelOffsets.ElementAt(i).Value);
            }

            //Fix control commands.
            for (int i = 0; i < Commands.Count; i++)
            {
                //Make sure the command is a control command.
                if ((CommandType)Commands[i].Identifier == CommandType.Call || (CommandType)Commands[i].Identifier == CommandType.Jump || (CommandType)Commands[i].Identifier == CommandType.OpenTrack || (CommandType)Commands[i].Identifier == CommandType.If)
                {
                    if ((CommandType)Commands[i].Identifier == CommandType.If)
                    {
                        //The first parameter is going to be the offset.
                        int offset = 0;
                        if ((CommandType)((IfCommand)Commands[i]).SequenceCommand.Identifier == CommandType.Call || (CommandType)((IfCommand)Commands[i]).SequenceCommand.Identifier == CommandType.Jump)
                        {
                            offset = (int)((UInt24)((IfCommand)Commands[i]).SequenceCommand.Parameters[0]).Value;
                        }
                        else if ((CommandType)((IfCommand)Commands[i]).SequenceCommand.Identifier == CommandType.OpenTrack)
                        {
                            offset = (int)((UInt24)((IfCommand)Commands[i]).SequenceCommand.Parameters[1]).Value;
                        }

                        //Get the index.
                        int index = OffsetToCommandIndex(Commands, offset);

                        //Set the property to this.
                        if ((CommandType)((IfCommand)Commands[i]).SequenceCommand.Identifier == CommandType.Call || (CommandType)((IfCommand)Commands[i]).SequenceCommand.Identifier == CommandType.Jump)
                        {
                            ((UInt24)((IfCommand)Commands[i]).SequenceCommand.Parameters[0]).Value = (uint)index;
                        }
                        else if ((CommandType)((IfCommand)Commands[i]).SequenceCommand.Identifier == CommandType.OpenTrack)
                        {
                            ((UInt24)((IfCommand)Commands[i]).SequenceCommand.Parameters[1]).Value = (uint)index;
                        }
                    }
                    else
                    {
                        //The first parameter is going to be the offset.
                        int offset = 0;
                        if ((CommandType)Commands[i].Identifier == CommandType.Call || (CommandType)Commands[i].Identifier == CommandType.Jump)
                        {
                            offset = (int)((UInt24)Commands[i].Parameters[0]).Value;
                        }
                        else
                        {
                            offset = (int)((UInt24)Commands[i].Parameters[1]).Value;
                        }

                        //Get the index.
                        int index = OffsetToCommandIndex(Commands, offset);

                        //Set the property to this.
                        if ((CommandType)Commands[i].Identifier == CommandType.Call || (CommandType)Commands[i].Identifier == CommandType.Jump)
                        {
                            ((UInt24)Commands[i].Parameters[0]).Value = (uint)index;
                        }
                        else
                        {
                            ((UInt24)Commands[i].Parameters[1]).Value = (uint)index;
                        }
                    }
                }
            }

            //Update private offsets.
            RefreshPrivateOffsets();

            //Free.
            br.Dispose();
        }
예제 #5
0
        /// <summary>
        /// Read a sequence command.
        /// </summary>
        /// <param name="br">The reader.</param>
        /// <param name="type">Type of sequence command.</param>
        /// <returns>The read sequence command.</returns>
        public static SequenceCommand Read(BinaryDataReader br, SequenceCommandType type = SequenceCommandType.Normal)
        {
            //Get sequence command.
            SequenceCommand s = null;

            switch (type)
            {
            case SequenceCommandType.Normal:
                s = NewFromType(br.ReadByte(), (int)br.Position);
                break;

            case SequenceCommandType.Extended:
                s = NewFromTypeExtended(br.ReadByte(), (int)br.Position);
                break;
            }

            //Read the objects.
            int count = 0;

            foreach (var t in s.SequenceParameterTypes)
            {
                //Switch the type.
                switch (t)
                {
                //U8.
                case SequenceParameterType.u8:
                    s.Parameters[count] = br.ReadByte();
                    break;

                //U16.
                case SequenceParameterType.u16:
                    s.Parameters[count] = br.ReadUInt16();
                    break;

                //U24.
                case SequenceParameterType.u24:
                    s.Parameters[count] = new UInt24(br);
                    break;

                //U32.
                case SequenceParameterType.u32:
                    s.Parameters[count] = br.ReadUInt32();
                    break;

                //U64.
                case SequenceParameterType.u64:
                    s.Parameters[count] = br.ReadUInt64();
                    break;

                //S8.
                case SequenceParameterType.s8:
                    s.Parameters[count] = br.ReadSByte();
                    break;

                //S16.
                case SequenceParameterType.s16:
                    s.Parameters[count] = br.ReadInt16();
                    break;

                //S32.
                case SequenceParameterType.s32:
                    s.Parameters[count] = br.ReadInt32();
                    break;

                //S64.
                case SequenceParameterType.s64:
                    s.Parameters[count] = br.ReadInt64();
                    break;

                //Boolean.
                case SequenceParameterType.boolean:
                    s.Parameters[count] = br.ReadBoolean();
                    break;

                //Variable length.
                case SequenceParameterType.VariableLength:
                    s.Parameters[count] = VariableLength.ReadVariableLength(br);
                    break;

                //Sequence command.
                case SequenceParameterType.SeqCommand:

                    //The type of sequence command embedded depends on the command type.
                    switch ((CommandType)s.Identifier)
                    {
                    //Extended.
                    case CommandType.Extended:
                        s.Parameters[count] = Read(br, SequenceCommandType.Extended);
                        break;

                    //Random.
                    case CommandType.Random:
                        s.Parameters[count] = NewFromType(br.ReadByte(), (int)br.Position);

                        //Extended.
                        if (((SequenceCommand)s.Parameters[count]).Identifier == (byte)CommandType.Extended)
                        {
                            //Read a new extended command.
                            ((SequenceCommand)s.Parameters[count]).Parameters[0] = NewFromTypeExtended(br.ReadByte(), (int)br.Position);

                            //Remove the last parameter of the sequence command.
                            ((SequenceCommand)((SequenceCommand)s.Parameters[count]).Parameters[0]).SequenceParameterTypes.RemoveAt(((SequenceCommand)((SequenceCommand)s.Parameters[count]).Parameters[0]).SequenceParameterTypes.Count - 1);

                            //Read the parameters.
                            ((SequenceCommand)((SequenceCommand)s.Parameters[count]).Parameters[0]).ReadPrefixParameters(br);
                        }

                        //Regular.
                        else
                        {
                            //Remove the last parameter, since it is replaced with the min and max.
                            ((SequenceCommand)s.Parameters[count]).SequenceParameterTypes.RemoveAt(((SequenceCommand)s.Parameters[count]).SequenceParameterTypes.Count - 1);
                            ((SequenceCommand)s.Parameters[count]).ReadPrefixParameters(br);
                        }
                        break;

                    //Variable.
                    case CommandType.Variable:
                        s.Parameters[count] = NewFromType(br.ReadByte(), (int)br.Position);

                        //Extended.
                        if (((SequenceCommand)s.Parameters[count]).Identifier == (byte)CommandType.Extended)
                        {
                            //Read a new extended command.
                            ((SequenceCommand)s.Parameters[count]).Parameters[0] = NewFromTypeExtended(br.ReadByte(), (int)br.Position);

                            //Remove the last parameter of the sequence command.
                            ((SequenceCommand)((SequenceCommand)s.Parameters[count]).Parameters[0]).SequenceParameterTypes.RemoveAt(((SequenceCommand)((SequenceCommand)s.Parameters[count]).Parameters[0]).SequenceParameterTypes.Count - 1);

                            //Read the parameters.
                            ((SequenceCommand)((SequenceCommand)s.Parameters[count]).Parameters[0]).ReadPrefixParameters(br);
                        }

                        //Regular.
                        else
                        {
                            //Remove the last parameter, since it is replaced with the min and max.
                            ((SequenceCommand)s.Parameters[count]).SequenceParameterTypes.RemoveAt(((SequenceCommand)s.Parameters[count]).SequenceParameterTypes.Count - 1);
                            ((SequenceCommand)s.Parameters[count]).ReadPrefixParameters(br);
                        }
                        break;

                    //Last resort.
                    default:
                        s.Parameters[count] = Read(br);
                        break;
                    }
                    break;
                }

                //Increase count.
                count++;
            }

            //Return the command.
            return(s);
        }
예제 #6
0
        /// <summary>
        /// Return the string of a prefix command.
        /// </summary>
        /// <param name="c">The prefix command.</param>
        /// <returns>The prefix command as a string,</returns>
        public string PrefixToSeqString(SequenceCommand c, Dictionary <string, int> publicLabels)
        {
            //Random.
            if ((CommandType)c.Identifier == CommandType.Random)
            {
                //Get string.
                RemoveNullFromCommand(c);
                string s = (c as RandomCommand).SequenceCommand.ToSeqString(publicLabels).Replace("\t", " ");

                //If no space, add at end.
                if (!s.Contains(" "))
                {
                    return(s + "_r " + (c as RandomCommand).Min + ", " + (c as RandomCommand).Max);
                }

                //Add after first space.
                s = s.Substring(0, s.IndexOf(" ")) + "_r " + s.Substring(s.IndexOf(" "), s.LastIndexOf(" ") + 1 - s.IndexOf(" "));
                return(s + (c as RandomCommand).Min + ", " + (c as RandomCommand).Max);
            }

            //Variable.
            if ((CommandType)c.Identifier == CommandType.Variable)
            {
                //Get string.
                RemoveNullFromCommand(c);
                string s = (c as VariableCommand).SequenceCommand.ToSeqString(publicLabels).Replace("\t", " ");

                //If no space, add at end.
                if (!s.Contains(" "))
                {
                    return(s + "_v " + (c as VariableCommand).Variable);
                }

                //Add after first space.
                s = s.Substring(0, s.IndexOf(" ")) + "_v " + s.Substring(s.IndexOf(" "), s.LastIndexOf(" ") + 1 - s.IndexOf(" "));
                return(s + (c as VariableCommand).Variable);
            }

            //If.
            if ((CommandType)c.Identifier == CommandType.If)
            {
                //Get string.
                string s = (c as IfCommand).SequenceCommand.ToSeqString(publicLabels).Replace("\t", " ");

                //If no space, add at end.
                if (!s.Contains(" "))
                {
                    return(s + "_if");
                }

                //Add after first space.
                return(s.Substring(0, s.IndexOf(" ")) + "_if" + s.Substring(s.IndexOf(" "), s.Length - s.IndexOf(" ")));
            }

            //Time change.
            if ((CommandType)c.Identifier == CommandType.TimeChange)
            {
                //Get string.
                RemoveNullFromCommand(c);
                string s = (c as TimeChangeCommand).SequenceCommand.ToSeqString(publicLabels).Replace("\t", " ");
                return(s + "_t " + (c as TimeChangeCommand).Ticks);
            }

            //Time random.
            if ((CommandType)c.Identifier == CommandType.TimeRandom)
            {
                //Get string.
                RemoveNullFromCommand(c);
                string s = (c as TimeChangeRandomCommand).SequenceCommand.ToSeqString(publicLabels).Replace("\t", " ");
                return(s + "_tr " + (c as TimeChangeRandomCommand).Min + ", " + (c as TimeChangeRandomCommand).Max);
            }

            //Time variable.
            if ((CommandType)c.Identifier == CommandType.TimeVariable)
            {
                //Get string.
                RemoveNullFromCommand(c);
                string s = (c as TimeChangeVariableCommand).SequenceCommand.ToSeqString(publicLabels).Replace("\t", " ");
                return(s + "_tv " + (c as TimeChangeVariableCommand).VariableNumber);
            }

            //Last resort.
            return("");
        }
예제 #7
0
        /// <summary>
        /// Return the string of an extended command.
        /// </summary>
        /// <param name="c">The extended command.</param>
        /// <returns>The extended command as a string,</returns>
        public string ExtendedToSeqString(SequenceCommand c)
        {
            //Switch the type.
            switch ((ExtendedCommandType)c.Identifier)
            {
            //Set var.
            case ExtendedCommandType.SetVar:
                return("setvar " + (c as SetVarCommand).Variable + ", " + (c as SetVarCommand).Value);

            //Add var.
            case ExtendedCommandType.AddVar:
                return("addvar " + (c as AddVarCommand).Variable + ", " + (c as AddVarCommand).Value);

            //Subtract var.
            case ExtendedCommandType.SubtractVar:
                return("subvar " + (c as SubtractVarCommand).Variable + ", " + (c as SubtractVarCommand).Value);

            //Multiply var.
            case ExtendedCommandType.MultiplyVar:
                return("mulvar " + (c as MultiplyVarCommand).Variable + ", " + (c as MultiplyVarCommand).Value);

            //Divide var.
            case ExtendedCommandType.DivideVar:
                return("divvar " + (c as DivideVarCommand).Variable + ", " + (c as DivideVarCommand).Value);

            //Shift var.
            case ExtendedCommandType.ShiftVar:
                return("shiftvar " + (c as ShiftVarCommand).Variable + ", " + (c as ShiftVarCommand).Value);

            //Random var.
            case ExtendedCommandType.RandomVar:
                return("randvar " + (c as RandomVarCommand).Variable + ", " + (c as RandomVarCommand).Value);

            //And var.
            case ExtendedCommandType.AndVar:
                return("andvar " + (c as AndVarCommand).Variable + ", " + (c as AndVarCommand).Value);

            //Or var.
            case ExtendedCommandType.OrVar:
                return("orvar " + (c as OrVarCommand).Variable + ", " + (c as OrVarCommand).Value);

            //Xor var.
            case ExtendedCommandType.XorVar:
                return("xorvar " + (c as XorVarCommand).Variable + ", " + (c as XorVarCommand).Value);

            //Not var.
            case ExtendedCommandType.NotVar:
                return("notvar " + (c as NotVarCommand).Variable + ", " + (c as NotVarCommand).Value);

            //Mod var.
            case ExtendedCommandType.ModVar:
                return("modvar " + (c as ModVarCommand).Variable + ", " + (c as ModVarCommand).Value);

            //Compare equal.
            case ExtendedCommandType.CompareEqual:
                return("cmp_eq " + (c as CompareEqualCommand).Variable + ", " + (c as CompareEqualCommand).Value);

            //Compare greater than or equal to.
            case ExtendedCommandType.CompareGreaterThanOrEqualTo:
                return("cmp_ge " + (c as CompareGreaterThanOrEqualToCommand).Variable + ", " + (c as CompareGreaterThanOrEqualToCommand).Value);

            //Compare greater than.
            case ExtendedCommandType.CompareGreaterThan:
                return("cmp_gt " + (c as CompareGreaterThanCommand).Variable + ", " + (c as CompareGreaterThanCommand).Value);

            //Compare less than or equal to.
            case ExtendedCommandType.CompareLessThanOrEqualTo:
                return("cmp_le " + (c as CompareLessThanOrEqualToCommand).Variable + ", " + (c as CompareLessThanOrEqualToCommand).Value);

            //Compare less than.
            case ExtendedCommandType.CompareLessThan:
                return("cmp_lt " + (c as CompareLessThanCommand).Variable + ", " + (c as CompareLessThanCommand).Value);

            //Compare not equal.
            case ExtendedCommandType.CompareNotEqual:
                return("cmp_ne " + (c as CompareNotEqualCommand).Variable + ", " + (c as CompareNotEqualCommand).Value);

            //Mod 2 curve.
            case ExtendedCommandType.Mod2Curve:
                return("mod2_curve " + ((byte)(c as Mod2CurveCommand).Curve));

            //Mod 2 phase.
            case ExtendedCommandType.Mod2Phase:
                return("mod2_phase " + (c as Mod2PhaseCommand).Phase);

            //Mod 2 depth.
            case ExtendedCommandType.Mod2Depth:
                return("mod2_depth " + (c as Mod2DepthCommand).Depth);

            //Mod 2 speed.
            case ExtendedCommandType.Mod2Speed:
                return("mod2_speed " + (c as Mod2SpeedCommand).Speed);

            //Mod 2 type.
            case ExtendedCommandType.Mod2Type:
                return("mod2_type " + ((byte)(c as Mod2TypeCommand).Type));

            //Mod 2 range.
            case ExtendedCommandType.Mod2Range:
                return("mod2_range " + (c as Mod2RangeCommand).Range);

            //Mod 3 curve.
            case ExtendedCommandType.Mod3Curve:
                return("mod3_curve " + ((byte)(c as Mod3CurveCommand).Curve));

            //Mod 3 phase.
            case ExtendedCommandType.Mod3Phase:
                return("mod3_phase " + (c as Mod3PhaseCommand).Phase);

            //Mod 3 depth.
            case ExtendedCommandType.Mod3Depth:
                return("mod3_depth " + (c as Mod3DepthCommand).Depth);

            //Mod 3 speed.
            case ExtendedCommandType.Mod3Speed:
                return("mod3_speed " + (c as Mod3SpeedCommand).Speed);

            //Mod 3 type.
            case ExtendedCommandType.Mod3Type:
                return("mod3_type " + ((byte)(c as Mod3TypeCommand).Type));

            //Mod 3 range.
            case ExtendedCommandType.Mod3Range:
                return("mod3_range " + (c as Mod3RangeCommand).Range);

            //Mod 4 curve.
            case ExtendedCommandType.Mod4Curve:
                return("mod4_curve " + ((byte)(c as Mod4CurveCommand).Curve));

            //Mod 4 phase.
            case ExtendedCommandType.Mod4Phase:
                return("mod4_phase " + (c as Mod4PhaseCommand).Phase);

            //Mod 4 depth.
            case ExtendedCommandType.Mod4Depth:
                return("mod4_depth " + (c as Mod4DepthCommand).Depth);

            //Mod 4 speed.
            case ExtendedCommandType.Mod4Speed:
                return("mod4_speed " + (c as Mod4SpeedCommand).Speed);

            //Mod 4 type.
            case ExtendedCommandType.Mod4Type:
                return("mod4_type " + ((byte)(c as Mod4TypeCommand).Type));

            //Mod 4 range.
            case ExtendedCommandType.Mod4Range:
                return("mod4_range " + (c as Mod4RangeCommand).Range);

            //Function.
            case ExtendedCommandType.Function:
                return("userproc " + (c as FunctionCommand).Function);

            //Mod 2 delay.
            case ExtendedCommandType.Mod2Delay:
                return("mod2_delay " + (c as Mod2DelayCommand).Delay);

            //Mod 2 period.
            case ExtendedCommandType.Mod2Period:
                return("mod2_period " + (c as Mod2PeriodCommand).Period);

            //Mod 3 delay.
            case ExtendedCommandType.Mod3Delay:
                return("mod3_delay " + (c as Mod3DelayCommand).Delay);

            //Mod 3 period.
            case ExtendedCommandType.Mod3Period:
                return("mod3_period " + (c as Mod3PeriodCommand).Period);

            //Mod 4 delay.
            case ExtendedCommandType.Mod4Delay:
                return("mod4_delay " + (c as Mod4DelayCommand).Delay);

            //Mod 4 period.
            case ExtendedCommandType.Mod4Period:
                return("mod4_period " + (c as Mod4PeriodCommand).Period);

            //Last case.
            default:
                return("");
            }
        }