Пример #1
0
        public virtual IList <OutputFile> ProcessStream(Stream input, ConvertOptions options)
        {
            List <RPCCommand> rpc = new List <RPCCommand>();

            using (BinaryReader reader = new BinaryReader(input))
            {
                reader.ReadInt16();
                int  length = reader.ReadInt16();
                byte lastb  = 0;
                int  delay  = 0;
                for (int i = 0; i < length; i++)
                {
                    byte b = reader.ReadByte();
                    if (b != lastb)
                    {
                        rpc.Add(RPCCommand.Delay(delay * 1000 / 140));
                        delay = 0;
                    }
                    if (b == 0)
                    {
                        rpc.Add(RPCCommand.ClearCountdown());
                    }
                    else
                    {
                        double freq = b * 15;                      //frequencies[b];
                        rpc.Add(RPCCommand.SetCountdown(LoadMDT.FrequencyToCountdown(freq)));
                    }
                    delay += 1;
                    lastb  = b;
                }
                rpc.Add(RPCCommand.Delay(delay * 1000 / 140));
            }
            return(LoadPCS.ProcessRPC(rpc, options));
        }
Пример #2
0
            public IEnumerable <RPCCommand> GetCommands(string ppMusicString)
            {
                int pos = 0;

                while (NextNote(ppMusicString, ref pos))
                {
                    double freq = Note2Freq(Note) * 2;
                    NoteTime += NoteDuration;
                    State     = PlayerState.Parsing;
                    double silence = 0;
                    if (Mode == PlayerMode.Normal)
                    {
                        silence = NoteDuration / 8;
                    }
                    else if (Mode == PlayerMode.Staccato)
                    {
                        silence = NoteDuration / 4;
                    }
                    if (freq > 0)
                    {
                        yield return(RPCCommand.SetCountdown(LoadMDT.FrequencyToCountdown(freq)));
                    }
                    else
                    {
                        yield return(RPCCommand.ClearCountdown());
                    }
                    yield return(RPCCommand.Delay((int)Math.Round((NoteDuration - silence) * 1000)));

                    if (silence > 0)
                    {
                        yield return(RPCCommand.ClearCountdown());

                        yield return(RPCCommand.Delay((int)Math.Round(silence * 1000)));
                    }
                }
            }
Пример #3
0
        public override IList <OutputFile> ProcessStream(Stream input, ConvertOptions options)
        {
            List <RPCCommand> rpc = new List <RPCCommand>();

            Channel[] channels    = new Channel[16];
            int       lastchannel = -1;
            int       time        = 0;

            using (BinaryReader reader = new BinaryReader(input))
            {
                try{
                    if (options.MultiChannel)
                    {
                        while (true)
                        {
                            byte command = reader.ReadByte();
                            if ((command & 0x80) != 0)
                            {
                                switch (command & 0xF0)
                                {
                                case 0x90:                                         //Play
                                    int    channel = command & 0x0F;
                                    int    note    = reader.ReadByte();
                                    double freq    = NoteToFrequency(note);
                                    rpc.Add(new RPCCommand(RPCCommandType.SetCountdown, channel, FrequencyToCountdown(freq)));
                                    break;

                                case 0x80:                                         //Stop
                                    channel = command & 0x0F;
                                    rpc.Add(RPCCommand.ClearCountdown(channel));
                                    break;

                                case 0xF0:
                                case 0xE0:                                                    //End
                                    throw new EndOfStreamException();
                                }
                            }
                            else                               //Delay
                            {
                                byte next  = reader.ReadByte();
                                int  delay = (command << 8) | next;
                                time += delay;
                                rpc.Add(RPCCommand.Delay(delay));
                            }
                        }
                    }
                    else
                    {
                        while (true)
                        {
                            byte command = reader.ReadByte();
                            if ((command & 0x80) != 0)
                            {
                                switch (command & 0xF0)
                                {
                                case 0x90:                                         //Play
                                    int channel = command & 0x0F;
                                    lastchannel = channel;
                                    int note = reader.ReadByte();
                                    channels[channel].Frequency = NoteToFrequency(note);
                                    channels[channel].StartTime = time;
                                    double freq = FinalFrequency(channels);
                                    rpc.Add(new RPCCommand(RPCCommandType.SetCountdown, FrequencyToCountdown(freq)));
                                    break;

                                case 0x80:                                         //Stop
                                    channel = command & 0x0F;
                                    channels[channel].Frequency = 0;
                                    if (channels.All(p => p.Frequency == 0))
                                    {
                                        rpc.Add(RPCCommand.ClearCountdown());
                                    }
                                    else
                                    {
                                        freq = FinalFrequency(channels);
                                        rpc.Add(new RPCCommand(RPCCommandType.SetCountdown, FrequencyToCountdown(freq)));
                                    }
                                    break;

                                case 0xF0:
                                case 0xE0:                                                    //End
                                    throw new EndOfStreamException();
                                }
                            }
                            else                               //Delay
                            {
                                byte next  = reader.ReadByte();
                                int  delay = (command << 8) | next;
                                //if(delay == 0) delay = 50;
                                time += delay;
                                rpc.Add(RPCCommand.Delay(delay));
                            }
                        }
                    }
                }catch (EndOfStreamException)
                {
                }
            }

            return(new[] { new OutputFile(options.OutputPath, rpc) });
        }
Пример #4
0
        public static List <RPCCommand> ProcessPCS(IList <Command> commands, ConvertOptions options)
        {
            List <RPCCommand> rpc = new List <RPCCommand>();

            bool          enabled   = false;
            int           starttime = -1;
            int           lasttime  = 0;
            FrequencyMode freqmode  = 0;

            int?setcountdown = null;

            var e = commands.GetEnumerator();

            while (e.MoveNext())
            {
                if (starttime == -1)
                {
                    starttime = e.Current.Time;
                }
                else
                {
                    int timedelta = e.Current.Time - lasttime;
                    if (timedelta > 0)
                    {
                        rpc.Add(RPCCommand.Delay(timedelta));
                    }
                }
                lasttime = e.Current.Time;
                if (e.Current is EnableCommand)
                {
                    enabled = ((EnableCommand)e.Current).Enable;
                    if (enabled == false)
                    {
                        rpc.Add(RPCCommand.ClearCountdown());
                    }
                    else if (setcountdown != null)
                    {
                        rpc.Add(new RPCCommand(RPCCommandType.SetCountdown, setcountdown.Value));
                        setcountdown = null;
                    }
                }
                else if (e.Current is FrequencyModeCommand)
                {
                    freqmode = ((FrequencyModeCommand)e.Current).Mode;
                }
                else if (e.Current is FrequencyByte1Command && freqmode != 0)
                {
                    if (freqmode == FrequencyMode.Countdown || freqmode == FrequencyMode.FrequencyDivider)
                    {
                        int countdown = ((FrequencyByte1Command)e.Current).Value;
                        e.MoveNext();
                        try{
                            countdown |= ((FrequencyByte2Command)e.Current).Value << 8;
                            //if(countdown != 0)
                            // /*if(enabled) */rpc.Add(new RPCCommand(RPCCommandType.SetCountdown, countdown));
                            if (enabled)
                            {
                                rpc.Add(new RPCCommand(RPCCommandType.SetCountdown, countdown));
                            }
                            else
                            {
                                setcountdown = countdown;
                            }
                        }catch (InvalidCastException)
                        {
                            Program.Error("Missing countdown pair for $42.");
                        }
                    }
                    else
                    {
                        Program.Warning("Unknown value {0:x} for port $42.", freqmode);
                    }
                }
                else
                {
                    Program.Warning("Unknown port ${0:x}.", e.Current.Port);
                }
            }

            return(rpc);
        }
Пример #5
0
        public static IList <OutputFile> ProcessRPC(List <RPCCommand> rpc, ConvertOptions options)
        {
            bool informed = false;

            for (int i = 0; i < rpc.Count; i++)
            {
                var cmd = rpc[i];
                if (cmd.Type == RPCCommandType.SetCountdown)
                {
                    if (cmd.Data <= 36 || cmd.Data > 32248)
                    {
                        if (options.PCS_Sanitize)
                        {
                            rpc.RemoveAt(i);
                            i -= 1;
                        }
                        else if (!informed)
                        {
                            informed = true;
                            Console.WriteLine("Input contains frequencies ({0}) outside the standard range, use --sanitize to remove them.", 1193180 / cmd.Data);
                        }
                    }
                }
                if (cmd.Type == RPCCommandType.Delay && cmd.Data == 0)
                {
                    rpc.RemoveAt(i);
                    i -= 1;
                }
                else if (cmd.Type == RPCCommandType.Delay)
                {
                    if (i + 1 < rpc.Count && rpc[i + 1].Type == RPCCommandType.Delay)
                    {
                        int delay = cmd.Data + rpc[i + 1].Data;
                        rpc[i] = new RPCCommand(RPCCommandType.Delay, delay);
                        rpc.RemoveAt(i + 1);
                        i -= 1;
                    }
                }
                else
                {
                    if (i + 1 < rpc.Count && rpc[i + 1].Type == cmd.Type && rpc[i + 1].Data == cmd.Data)
                    {
                        rpc.RemoveAt(i);
                        i -= 1;
                    }
                }
            }

            if (options.PCS_Trim)
            {
                for (int i = 0; i < rpc.Count; i++)
                {
                    var cmd = rpc[i];
                    if (cmd.Type == RPCCommandType.SetCountdown)
                    {
                        break;
                    }
                    else
                    {
                        rpc.RemoveAt(i);
                        i -= 1;
                    }
                }
                for (int i = rpc.Count - 1; i >= 0; i--)
                {
                    var cmd = rpc[i];
                    if (cmd.Type == RPCCommandType.SetCountdown)
                    {
                        break;
                    }
                    else
                    {
                        rpc.RemoveAt(i);
                    }
                }
            }

            IList <OutputFile> files;

            if (options.PCS_Split)
            {
                bool playing = false;
                files = rpc.Split(
                    c => c.Type == RPCCommandType.SetCountdown ? (playing = true) && false : c.Type == RPCCommandType.ClearCountdown ? (playing = false) && false : c.Type == RPCCommandType.Delay ? c.Data >= options.PCS_SplitDelay * 1000 && !playing : false
                    ).Select((d, i) => new OutputFile(Path.ChangeExtension(Path.ChangeExtension(options.OutputPath, null) + i.ToString("000"), options.Extension), d)).ToList();
            }
            else
            {
                files = new[] { new OutputFile(options.OutputPath, rpc) };
            }

            if (options.PCS_Crop)
            {
                foreach (var file in files)
                {
                    var data  = file.Data;
                    int start = 0;
                    for (int i = 0; i < data.Count; i++)
                    {
                        var cmd = data[i];
                        if (cmd.Type == RPCCommandType.SetCountdown)
                        {
                            start = i; break;
                        }
                    }
                    for (int i = start + 1; i < data.Count; i++)
                    {
                        var cmd = data[i];
                        if (cmd.Type == RPCCommandType.Delay)
                        {
                            continue;
                        }
                        for (int j = i; j < data.Count; j++)
                        {
                            var left  = data[start + j - i];
                            var right = data[j];
                            if (left.Type != right.Type)
                            {
                                break;
                            }
                            if (left.Type == RPCCommandType.SetCountdown ? left.Data != right.Data : false)
                            {
                                break;
                            }
                            if (left.Type == RPCCommandType.Delay ? right.Data < left.Data - 2 || right.Data > left.Data + 2 : false)
                            {
                                break;
                            }
                            if (j - i > options.PCS_CropSimilarity || (j == data.Count - 3 && j - i > 5))
                            {
                                data.RemoveRange(i, data.Count - i);
                            }
                        }
                    }
                }
            }

            if (options.PCS_TrimLength)
            {
                foreach (var file in files)
                {
                    var data = new List <RPCCommand>(file.Data);
                    int time = 0;
                    for (int i = 0; i < data.Count; i++)
                    {
                        var cmd = data[i];
                        if (cmd.Type == RPCCommandType.Delay)
                        {
                            time += cmd.Data;
                            if (time > options.PCS_NewLength)
                            {
                                data[i] = new RPCCommand(cmd.Type, cmd.Channel, cmd.DelayValue - (time - options.PCS_NewLength));
                                data.RemoveRange(i + 1, data.Count - (i + 1));
                                data.Add(RPCCommand.ClearCountdown());
                            }
                        }
                    }
                }
            }

            if (options.PCS_Repeat)
            {
                foreach (var file in files)
                {
                    var data = new List <RPCCommand>(file.Data);
                    for (int i = 0; i < options.PCS_RepeatCount - 1; i++)
                    {
                        file.Data.AddRange(data);
                    }
                }
            }


            if (options.Optimize)
            {
                foreach (var file in files)
                {
                    var data = file.Data;

                    int?lastfreq = null;
                    for (int i = 0; i < data.Count; i++)
                    {
                        var cmd = data[i];
                        if (cmd.Type == RPCCommandType.SetCountdown)
                        {
                            if (lastfreq != null && Math.Abs(lastfreq.Value - cmd.Data) <= 1)
                            {
                                lastfreq = cmd.Data;
                                data.RemoveAt(i);
                                i -= 1;
                            }
                            else
                            {
                                lastfreq = cmd.Data;
                            }
                        }
                        else if (cmd.Type == RPCCommandType.ClearCountdown)
                        {
                            lastfreq = null;
                        }
                    }
                }
            }

            if (options.OutputType == "dro")
            {
                //Separates pairs of SetCountdown/ClearCountdown by a Delay: 0
                //Required for DRO rendering

                foreach (var file in files)
                {
                    var data = file.Data;

                    bool isclick = false;
                    for (int i = 0; i < data.Count; i++)
                    {
                        var cmd = data[i];
                        if (cmd.Type == RPCCommandType.SetCountdown)
                        {
                            isclick = true;
                        }
                        else if (cmd.Type == RPCCommandType.Delay)
                        {
                            isclick = false;
                        }
                        else if (cmd.Type == RPCCommandType.ClearCountdown)
                        {
                            if (isclick)
                            {
                                data.Insert(i, RPCCommand.Delay(0));
                                i += 1;
                            }
                            isclick = false;
                        }
                    }
                }
            }

            return(files);
        }
Пример #6
0
        public static IList <OutputFile> ProcessRPC(List <RPCCommand> rpc, ConvertOptions options)
        {
            for (int i = 0; i < rpc.Count; i++)
            {
                var cmd = rpc[i];
                if (cmd.Type == RPCCommandType.Delay && cmd.Data == 0)
                {
                    rpc.RemoveAt(i);
                    i -= 1;
                }
                else if (cmd.Type == RPCCommandType.Delay)
                {
                    if (i + 1 < rpc.Count && rpc[i + 1].Type == RPCCommandType.Delay)
                    {
                        int delay = cmd.Data + rpc[i + 1].Data;
                        rpc[i] = new RPCCommand(RPCCommandType.Delay, delay);
                        rpc.RemoveAt(i + 1);
                        i -= 1;
                    }
                }
                else
                {
                    if (i + 1 < rpc.Count && rpc[i + 1].Type == cmd.Type && rpc[i + 1].Data == cmd.Data)
                    {
                        rpc.RemoveAt(i);
                        i -= 1;
                    }
                }
            }

            if (options.Trim)
            {
                for (int i = 0; i < rpc.Count; i++)
                {
                    var cmd = rpc[i];
                    if (cmd.Type == RPCCommandType.SetCountdown)
                    {
                        break;
                    }
                    else
                    {
                        rpc.RemoveAt(i);
                        i -= 1;
                    }
                }
                for (int i = rpc.Count - 1; i >= 0; i--)
                {
                    var cmd = rpc[i];
                    if (cmd.Type == RPCCommandType.SetCountdown)
                    {
                        break;
                    }
                    else
                    {
                        rpc.RemoveAt(i);
                    }
                }
            }

            IList <OutputFile> files;

            if (options.Split)
            {
                bool playing = false;
                files = rpc.Split(
                    c => c.Type == RPCCommandType.SetCountdown ? (playing = true) && false : c.Type == RPCCommandType.ClearCountdown ? (playing = false) && false : c.Type == RPCCommandType.Delay ? c.Data >= options.SplitDelay * 1000 && !playing : false
                    ).Select((d, i) => new OutputFile(Path.ChangeExtension(Path.ChangeExtension(options.OutputPath, null) + i.ToString("000"), options.Extension), d)).ToList();
            }
            else
            {
                files = new[] { new OutputFile(options.OutputPath, rpc) };
            }

            if (options.Crop)
            {
                foreach (var file in files)
                {
                    var data  = file.Data;
                    int start = 0;
                    for (int i = 0; i < data.Count; i++)
                    {
                        var cmd = data[i];
                        if (cmd.Type == RPCCommandType.SetCountdown)
                        {
                            start = i; break;
                        }
                    }
                    for (int i = start + 1; i < data.Count; i++)
                    {
                        var cmd = data[i];
                        if (cmd.Type == RPCCommandType.Delay)
                        {
                            continue;
                        }
                        for (int j = i; j < data.Count; j++)
                        {
                            var left  = data[start + j - i];
                            var right = data[j];
                            if (left.Type != right.Type)
                            {
                                break;
                            }
                            if (left.Type == RPCCommandType.SetCountdown ? left.Data != right.Data : false)
                            {
                                break;
                            }
                            if (left.Type == RPCCommandType.Delay ? right.Data < left.Data - 2 || right.Data > left.Data + 2 : false)
                            {
                                break;
                            }
                            if (j - i > options.CropSimilarity || (j == data.Count - 3 && j - i > 5))
                            {
                                data.RemoveRange(i, data.Count - i);
                            }
                        }
                    }
                }
            }

            if (options.TrimLength)
            {
                foreach (var file in files)
                {
                    var data = new List <RPCCommand>(file.Data);
                    int time = 0;
                    for (int i = 0; i < data.Count; i++)
                    {
                        var cmd = data[i];
                        if (cmd.Type == RPCCommandType.Delay)
                        {
                            time += cmd.Data;
                            if (time > options.NewLength)
                            {
                                data[i] = new RPCCommand(cmd.Type, cmd.Channel, cmd.DelayValue - (time - options.NewLength));
                                data.RemoveRange(i + 1, data.Count - (i + 1));
                                data.Add(RPCCommand.ClearCountdown());
                            }
                        }
                    }
                }
            }

            if (options.Repeat)
            {
                foreach (var file in files)
                {
                    var data = new List <RPCCommand>(file.Data);
                    for (int i = 0; i < options.RepeatCount - 1; i++)
                    {
                        file.Data.AddRange(data);
                    }
                }
            }

            return(files);
        }