Beispiel #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));
        }
Beispiel #2
0
 public virtual void ProcessFiles(IEnumerable <OutputFile> files, ConvertOptions options)
 {
     foreach (var file in files)
     {
         ProcessFile(file, options);
     }
 }
Beispiel #3
0
        public IEnumerable <ConvertOptions> GetInputs()
        {
            IEnumerable <string> files;
            IPathProcessor       pathProc;

            if (Program.PathProcessors.TryGetValue(InputType, out pathProc))
            {
                files = pathProc.GetInputs(InputPath);
            }
            else
            {
                files = Directory.EnumerateFiles(Path.GetDirectoryName(Path.GetFullPath(InputPath)), Path.GetFileName(InputPath));
            }

            foreach (string file in files)
            {
                ConvertOptions newOptions = (ConvertOptions)this.Clone();
                newOptions.InputPath = file;
                if (new Uri(Path.GetFullPath(InputPath)) != new Uri(Path.GetFullPath(file)))
                {
                    newOptions.OutputPath = Path.Combine(Path.GetDirectoryName(OutputPath), Path.GetFileName(Path.ChangeExtension(file, Extension)));
                }
                yield return(newOptions);
            }
        }
Beispiel #4
0
        public override IList <OutputFile> ProcessFile(string file, ConvertOptions options)
        {
            List <RPCCommand> rpc = new List <RPCCommand>();

            rpc.AddRange(QPlay.GetCommands(file));
            return(LoadPCS.ProcessRPC(rpc, options));
        }
Beispiel #5
0
        public override void ProcessFile(OutputFile file, ConvertOptions options)
        {
            file = new OutputFile(Path.GetTempFileName(), file.Data);
            save.ProcessFile(file, options);
            dro_player.Arguments = "/c dro_player \"" + file.Path + "\"";
            Process proc    = Process.Start(dro_player);
            Process ctlProc = proc;
            ConsoleCancelEventHandler oncancel = (o, a) => { a.Cancel = true; ctlProc.Kill(); };

            Console.CancelKeyPress += oncancel;
            try{
                int  read;
                bool first = true;
                while ((read = proc.StandardOutput.Read()) != -1)
                {
                    if (first)
                    {
                        ctlProc = GetChildProcesses(proc).FirstOrDefault() ?? proc;
                        first   = false;
                    }
                    Console.Write((char)read);
                }
                proc.WaitForExit();
            }finally{
                Console.CancelKeyPress -= oncancel;
                if (!proc.HasExited)
                {
                    proc.Kill();
                }
                File.Delete(file.Path);
            }
            Console.WriteLine();
        }
Beispiel #6
0
 public virtual IList <OutputFile> ProcessFile(string file, ConvertOptions options)
 {
     using (FileStream stream = new FileStream(file, FileMode.Open))
     {
         return(ProcessStream(stream, options));
     }
 }
Beispiel #7
0
 public override void ProcessFile(OutputFile file, ConvertOptions options)
 {
     using (var stream = new FileStream(file.Path, FileMode.Create))
     {
         Writer.SampleRate = options.Wave_Frequency ?? 44100;
         Writer.WriteWave(stream, CreateSong(file.Data, GetWaveform(options), options.Wave_Volume ?? 1.0, options.Wave_Clip ?? false, options.Wave_Frequency ?? 44100));
     }
 }
Beispiel #8
0
        private static void ProcessInput(ConvertOptions options)
        {
            var files = InputProcessors[options.InputType].ProcessFile(options.InputPath, options);

            var output = files.Where(f => !options.PCS_Filter || f.Data.Sum(cmd => cmd.Type == RPCCommandType.Delay ? cmd.Data : 0) > options.PCS_FilterDelay * 1000);

            OutputProcessors[options.OutputType].ProcessFiles(output, options);
        }
Beispiel #9
0
 public override void ProcessFile(OutputFile file, ConvertOptions options)
 {
     using (StreamWriter writer = new StreamWriter(new FileStream(file.Path, FileMode.Create)))
     {
         foreach (var cmd in file.Data)
         {
             writer.WriteLine(cmd.ToString());
         }
     }
 }
Beispiel #10
0
        public override void ProcessFile(OutputFile file, ConvertOptions options)
        {
            Console.WriteLine(file.Path);
            Console.WriteLine(TimeSpan.FromMilliseconds(file.Data.Sum(cmd => cmd.DelayValue)));
            Stopwatch sw  = new Stopwatch();
            var       rpc = file.Data;

            sw.Start();
            for (int i = 0; i < rpc.Count; i++)
            {
                var cmd = rpc[i];
                if (cmd.Type == RPCCommandType.SetCountdown || cmd.Type == RPCCommandType.ClearCountdown)
                {
                    int delay = 0;
                    for (int j = i + 1; j < rpc.Count; j++)
                    {
                        var cmd2 = rpc[j];
                        if (cmd2.Type == RPCCommandType.Delay)
                        {
                            delay += cmd2.Data;
                        }
                        else
                        {
                            i = j - 1;
                            break;
                        }
                    }
                    if (cmd.Type == RPCCommandType.SetCountdown)
                    {
                        int freq = 1193180 / cmd.Data;
                        if (freq >= 37 && freq <= 32767 && delay > 0)
                        {
                            Console.Beep(freq, delay);
                        }
                        else if (delay > 0)
                        {
                            Console.WriteLine("Bad frequency " + freq);
                            Thread.Sleep(delay);
                        }
                    }
                    else if (cmd.Type == RPCCommandType.ClearCountdown)
                    {
                        Thread.Sleep(delay);
                    }
                }
                else if (cmd.Type == RPCCommandType.Delay)
                {
                    Thread.Sleep(cmd.Data);
                }
                Console.Write(sw.Elapsed + "\r");
            }
            sw.Stop();
            Console.WriteLine();
        }
Beispiel #11
0
 public IEnumerable <ConvertOptions> GetInputs()
 {
     foreach (string file in Directory.EnumerateFiles(Path.GetDirectoryName(Path.GetFullPath(InputPath)), Path.GetFileName(InputPath)))
     {
         ConvertOptions newOptions = (ConvertOptions)this.Clone();
         newOptions.InputPath = file;
         if (new Uri(Path.GetFullPath(InputPath)) != new Uri(Path.GetFullPath(file)))
         {
             newOptions.OutputPath = Path.Combine(Path.GetDirectoryName(OutputPath), Path.GetFileName(Path.ChangeExtension(file, Extension)));
         }
         yield return(newOptions);
     }
 }
Beispiel #12
0
        public override IList <OutputFile> ProcessStream(Stream input, ConvertOptions options)
        {
            List <RPCCommand> rpc    = new List <RPCCommand>();
            StreamReader      reader = new StreamReader(input);
            string            line;

            while ((line = reader.ReadLine()) != null)
            {
                string[]       split = line.Split(new[] { ": " }, 0);
                RPCCommandType cmd   = (RPCCommandType)Enum.Parse(typeof(RPCCommandType), split[0]);
                int            value = Int32.Parse(split[1]);
                rpc.Add(new RPCCommand(cmd, value));
            }
            return(LoadPCS.ProcessRPC(rpc, options));
        }
Beispiel #13
0
        public override void ProcessFile(OutputFile file, ConvertOptions options)
        {
            Console.WriteLine(file.Path);
            Console.WriteLine(TimeSpan.FromMilliseconds(file.Data.Sum(cmd => cmd.DelayValue)));
            Console.WriteLine("Creating WAV...");
            var song = SaveWAV.CreateSong(file.Data, SaveWAV.GetWaveform(options), options.Wave_Volume ?? 1.0, options.Wave_Clip ?? false, options.Wave_Frequency ?? 44100, options.ClickLength, options.AutoTemper);

            Console.WriteLine("Playing...");
            using (var buffer = new MemoryStream())
            {
                SaveWAV.Writer.WriteWave(buffer, song);
                buffer.Position = 0;
                var player = new SoundPlayer(buffer);
                player.PlaySync();
            }
        }
Beispiel #14
0
        public static WaveFunction GetWaveform(ConvertOptions options)
        {
            if (options.Waveform.HasValue)
            {
                switch (options.Waveform.Value)
                {
                case 0:
                    return(WaveFunction.Sine);

                case 1:
                    return(WaveFunction.HalfSine);

                case 2:
                    return(WaveFunction.AbsSine);

                case 3:
                    return(WaveFunction.HalfAbsSine);

                case 4:
                default:
                    return(WaveFunction.Square);

                case 5:
                    return(WaveFunction.Triangle);

                case 6:
                    return(WaveFunction.Circle);

                case 7:
                    return(WaveFunction.AbsCircle);

                case 8:
                    return(WaveFunction.Sawtooth);

                case 9:
                    return(WaveFunction.Clausen);

                case 10:
                    return(WaveFunction.SineDouble);
                }
            }
            else
            {
                return(WaveFunction.Square);
            }
        }
Beispiel #15
0
        public override void ProcessFile(OutputFile file, ConvertOptions options)
        {
            using (BinaryWriter writer = new BinaryWriter(new FileStream(file.Path, FileMode.Create), Encoding.ASCII))
            {
                writer.Write((byte)0x08);
                writer.Write("MONOTONE".ToCharArray());
                writer.Write(new byte[82]);
                writer.Write(new byte[] { 1, 1, 1, 2, 0 });
                writer.Write(Enumerable.Repeat((byte)0xFF, 255).ToArray());

                byte lastb = 0;
                foreach (var cmd in file.Data)
                {
                    switch (cmd.Type)
                    {
                    case RPCCommandType.SetCountdown:
                        double freq = LoadMDT.CountdownToFrequency(cmd.Data);
                        var    bval = freq / 15;
                        if (bval > 255)
                        {
                            lastb = 0;
                        }
                        else
                        {
                            lastb = (byte)bval;
                        }
                        break;

                    case RPCCommandType.ClearCountdown:
                        lastb = 0;
                        break;

                    case RPCCommandType.Delay:
                        for (int i = 0; i < cmd.DelayValue * 60 / 1000.0; i++)
                        {
                            writer.Write((byte)0);
                            writer.Write(lastb);
                        }
                        break;
                    }
                }
            }
        }
Beispiel #16
0
        public virtual void ProcessFile(OutputFile file, ConvertOptions options)
        {
            using (var stream = new FileStream(file.Path, FileMode.Create))
            {
                var writer = new BinaryWriter(stream);
                writer.Write(0);
                byte lastb = 0;
                foreach (var cmd in file.Data)
                {
                    switch (cmd.Type)
                    {
                    case RPCCommandType.SetCountdown:
                        double freq = LoadMDT.CountdownToFrequency(cmd.Data);
                        var    bval = freq / 15;
                        if (bval > 255)
                        {
                            lastb = 0;
                        }
                        else
                        {
                            lastb = (byte)bval;
                        }
                        break;

                    case RPCCommandType.ClearCountdown:
                        lastb = 0;
                        break;

                    case RPCCommandType.Delay:
                        for (int i = 0; i < cmd.DelayValue * 140 / 1000.0; i++)
                        {
                            writer.Write(lastb);
                        }
                        break;
                    }
                }
                stream.Position = 2;
                writer.Write((short)(stream.Length - 4));
            }
        }
Beispiel #17
0
        public override void ProcessFile(OutputFile file, ConvertOptions options)
        {
            List <DROCommand> dro = new List <DROCommand>();

            if (options.MultiChannel)
            {
                for (int i = 0; i < 9; i++)
                {
                    dro.Add(new DROCommand(0x20 + oper1[i], 0x01));
                    dro.Add(new DROCommand(0x20 + oper1[i] + 3, 0x01));
                    dro.Add(new DROCommand(0x40 + oper1[i], 0x10));
                    dro.Add(new DROCommand(0x40 + oper1[i] + 3, 0x07));
                    dro.Add(new DROCommand(0x60 + oper1[i], 0xF0));
                    dro.Add(new DROCommand(0x60 + oper1[i] + 3, 0xF0));
                    dro.Add(new DROCommand(0x80 + oper1[i], 0x77));
                    dro.Add(new DROCommand(0x80 + oper1[i] + 3, 0x77));
                    dro.Add(new DROCommand(0xE0 + oper1[i], options.Waveform ?? 2));
                }
            }
            else
            {
                dro.Add(new DROCommand(0x20, 0x01));
                dro.Add(new DROCommand(0x23, 0x01));
                dro.Add(new DROCommand(0x40, 0x10));
                dro.Add(new DROCommand(0x43, 0x07));
                dro.Add(new DROCommand(0x60, 0xF0));
                dro.Add(new DROCommand(0x63, 0xF0));
                dro.Add(new DROCommand(0x80, 0x77));
                dro.Add(new DROCommand(0x83, 0x77));
                dro.Add(new DROCommand(0xE0, options.Waveform ?? 2));
            }
            if (options.DRO_PrefixCommands != null)
            {
                dro.AddRange(options.DRO_PrefixCommands);
            }

            bool informed = false;

            foreach (var cmd in file.Data)
            {
                if (cmd.Channel > 8)
                {
                    throw new ArgumentException("Only 9 channels are supported.");
                }
                switch (cmd.Type)
                {
                case RPCCommandType.Delay:
                    if (cmd.Data == 0)
                    {
                        if (options.ClickLength != null)
                        {
                            dro.AddRange(DROCommand.Delay(Math.Max(1, (int)Math.Round(options.ClickLength.Value))));
                        }
                        else
                        {
                            if (!informed)
                            {
                                Console.WriteLine("Song contains zero-length waves. Use --clicks 1 to render them as clicks.");
                                informed = true;
                            }
                            dro.AddRange(DROCommand.Delay(cmd.Data));
                        }
                    }
                    else
                    {
                        dro.AddRange(DROCommand.Delay(cmd.Data));
                    }
                    break;

                case RPCCommandType.SetCountdown:
                    double frequency = 1193180.0 / cmd.Data;
                    int    octave    = 4;
                    while (frequency > 780.0375)                            //0x03FF * 0.7625
                    {
                        frequency /= 2;
                        octave    += 1;
                        if (octave > 7)
                        {
                            break;
                        }
                    }
                    if (octave > 7)
                    {
                        dro.Add(new DROCommand(0xB0 | cmd.Channel, 0x10));
                    }
                    else
                    {
                        int fnum = (int)(frequency / 0.7625);
                        dro.Add(new DROCommand(0xA0 | cmd.Channel, fnum & 0x00FF));
                        dro.Add(new DROCommand(0xB0 | cmd.Channel, ((fnum & 0x0300) >> 8) | 0x20 | ((octave & 7) << 2)));
                    }
                    break;

                case RPCCommandType.ClearCountdown:
                    dro.Add(new DROCommand(0xB0 | cmd.Channel, 0x10));
                    break;
                }
            }

            if (options.DRO_EndDelay > 0)
            {
                dro.AddRange(DROCommand.Delay(options.DRO_EndDelay));
            }

            if (options.Optimize)
            {
                byte?[] registers = new byte?[0xFF];
                for (int i = 0; i < dro.Count; i++)
                {
                    DROCommand cmd = dro[i];
                    if (cmd.IsOPL)
                    {
                        if (registers[cmd.OPLRegister] == cmd.OPLValue)
                        {
                            dro.RemoveAt(i);
                            i -= 1;
                        }
                        registers[cmd.OPLRegister] = cmd.OPLValue;
                    }
                }
                for (int i = 0; i < dro.Count; i++)
                {
                    DROCommand cmd = dro[i];
                    if (cmd.IsDelay)
                    {
                        if (i + 1 < dro.Count && dro[i + 1].IsDelay)
                        {
                            int delay = cmd.DelayValue + dro[i + 1].DelayValue;
                            dro[i] = DROCommand.Delay(delay).First();
                            dro.RemoveAt(i + 1);
                            i -= 1;
                        }
                    }
                }
            }

            int bytesize = dro.Sum(cmd => cmd.Length);
            int timesize = dro.Sum(cmd => cmd.DelayValue);

            using (BinaryWriter writer = new BinaryWriter(new FileStream(file.Path, FileMode.Create), Encoding.ASCII))
            {
                writer.Write("DBRAWOPL".ToCharArray());
                writer.Write((short)0);
                writer.Write((short)1);
                writer.Write(timesize);
                writer.Write(bytesize);
                writer.Write((byte)0);
                writer.Write(new byte[3]);
                foreach (var cmd in dro)
                {
                    writer.Write((byte)cmd.Register);
                    writer.Write(cmd.Data);
                }
            }
        }
Beispiel #18
0
 public override IList <OutputFile> ProcessStream(Stream input, ConvertOptions options)
 {
     throw new NotImplementedException();
 }
Beispiel #19
0
 public abstract void ProcessFile(OutputFile file, ConvertOptions options);
Beispiel #20
0
        private static ConvertOptions ReadArguments(string[] args)
        {
            var options = new ConvertOptions();

            var    helpException = new Exception();
            string errorArg      = null;

            try{
                if (args.Length == 0)
                {
                    throw new ArgumentException("No arguments passed.");
                }
                var en = args.Cast <string>().GetEnumerator();
                while (en.MoveNext() && en.Current != null)
                {
                    errorArg = en.Current;

                    switch (en.Current.ToLower())
                    {
                    case "/w":
                    case "-w":
                    case "--waveform":
                        en.MoveNext();
                        options.Waveform = Int32.Parse(en.Current, CultureInfo.InvariantCulture);
                        break;

                    case "/o":
                    case "-o":
                    case "--opldata":
                        en.MoveNext();
                        string   oplstr = en.Current;
                        string[] ssplit = oplstr.Split('/', ',', ' ', '|', ':', ';', '-', '+');
                        options.DRO_PrefixCommands.AddRange(ssplit.Select((s, i) => new{ Index = i, Value = Byte.Parse(s, NumberStyles.HexNumber) }).GroupBy(x => x.Index / 2).Select(p => new DROCommand(p.ElementAt(0).Value, p.ElementAt(1).Value)));
                        break;

                    case "/t":
                    case "-t":
                    case "--trim":
                        options.PCS_Trim = true;
                        break;

                    case "/s":
                    case "-s":
                    case "--split":
                        options.PCS_Split = true;
                        en.MoveNext();
                        options.PCS_SplitDelay = Double.Parse(en.Current, CultureInfo.InvariantCulture);
                        break;

                    case "/f":
                    case "-f":
                    case "--filter":
                        options.PCS_Filter = true;
                        en.MoveNext();
                        options.PCS_FilterDelay = Double.Parse(en.Current, CultureInfo.InvariantCulture);
                        break;

                    case "/c":
                    case "-c":
                    case "--crop":
                        options.PCS_Crop = true;
                        en.MoveNext();
                        int sim = Int32.Parse(en.Current, CultureInfo.InvariantCulture);
                        if (sim == -1)
                        {
                            sim = Int32.MaxValue;
                        }
                        options.PCS_CropSimilarity = sim;
                        break;

                    case "/l":
                    case "-l":
                    case "--length":
                        options.PCS_TrimLength = true;
                        en.MoveNext();
                        options.PCS_NewLength = Int32.Parse(en.Current, CultureInfo.InvariantCulture);
                        break;

                    case "/d":
                    case "-d":
                    case "--delay":
                        options.DRO_EndDelay = 200;
                        break;

                    case "/n":
                    case "-n":
                    case "--no-optimalization":
                        options.Optimize = false;
                        break;

                    case "/m":
                    case "-m":
                    case "--multichannel":
                        options.MultiChannel = true;
                        break;

                    case "/r":
                    case "-r":
                    case "--repeat":
                        options.PCS_Repeat = true;
                        en.MoveNext();
                        options.PCS_RepeatCount = Int32.Parse(en.Current, CultureInfo.InvariantCulture);
                        break;

                    case "/in":
                    case "-in":
                    case "--input-type":
                        en.MoveNext();
                        options.InputType = en.Current;
                        break;

                    case "/out":
                    case "-out":
                    case "--output-type":
                        en.MoveNext();
                        options.OutputType = en.Current;
                        break;

                    case "/w:c":
                    case "-w:c":
                    case "--wave-clip":
                        options.Wave_Clip = true;
                        break;

                    case "/w:v":
                    case "-w:v":
                    case "--wave-volume":
                        en.MoveNext();
                        options.Wave_Volume = Double.Parse(en.Current, CultureInfo.InvariantCulture);
                        break;

                    case "/w:r":
                    case "-w:r":
                    case "--wave-sample-rate":
                        en.MoveNext();
                        options.Wave_Frequency = Int32.Parse(en.Current, CultureInfo.InvariantCulture);
                        break;

                    case "--sanitize":
                        options.PCS_Sanitize = true;
                        break;

                    case "--clicks":
                        en.MoveNext();
                        options.ClickLength = Double.Parse(en.Current, CultureInfo.InvariantCulture);
                        break;

                    case "--temper":
                        options.AutoTemper = true;
                        break;

                    case "?":
                    case "/?":
                    case "-?":
                    case "/h":
                    case "-h":
                    case "--help":
                        throw helpException;

                    default:
                        if (options.InputPath != null)
                        {
                            if (options.OutputPath != null)
                            {
                                throw new ArgumentException("Unexpected switch " + en.Current + ".");
                            }
                            options.OutputPath = en.Current;
                        }
                        else
                        {
                            options.InputPath = en.Current;
                        }
                        break;
                    }
                }
                if (options.InputPath == null)
                {
                    throw new ArgumentException("No path argument given.");
                }
                if (options.OutputPath == null)
                {
                    options.OutputPath = Path.ChangeExtension(options.InputPath, options.Extension);
                }

                IPathProcessor pathProc;
                if (!(PathProcessors.TryGetValue(options.InputType, out pathProc) && pathProc.IsValidPath(options.InputPath)) && !File.Exists(options.InputPath))
                {
                    throw new ArgumentException("Invalid path.");
                }
            }catch (Exception ex)
            {
                if (ex == helpException)
                {
                    Console.WriteLine("Usage: pcsconv [options] [input path] [output path]");
                    Console.WriteLine("Command-line arguments:");
                    Console.WriteLine("  -? -h --help                      -- Shows this help.");
                    Console.WriteLine("  -w --waveform [type]              -- Sets waveform type (default 2 for DRO and 4 for WAVE).");
                    Console.WriteLine("  -o --opldata [register:value:...] -- Additional OPL commands.");
                    Console.WriteLine("  -t --trim                         -- Trims delays from start and end.");
                    Console.WriteLine("  -f --filter                       -- Removes unnecessary sound noises.");
                    Console.WriteLine("  -s --split [mindelay]             -- Splits audio to multiple files.");
                    Console.WriteLine("  -n --no-optimalization            -- Disables removing redundant commands.");
                    Console.WriteLine("  -d --delay                        -- Adds 200ms delay to the end.");
                    Console.WriteLine("  -l --length [length]              -- Crops the output to the specified length (in ms).");
                    Console.WriteLine("  -m --multichannel                 -- Turns multichannel DRO on.");
                    Console.WriteLine("  -r --repeat [count]               -- Repeats the song n-times.");
                    Console.WriteLine("  -in  --input-type                 -- Specifies the input type (default is pcs).");
                    Console.WriteLine("  -out --output-type                -- Specifies the output type (default is dro).");
                    Console.WriteLine("Input types:");
                    Console.WriteLine(" pcs - RPC text output from the modified DOSBox version.");
                    Console.WriteLine(" mdt/bin - Binary output from MIDITONES.");
                    Console.WriteLine(" txt - simple RPC commands.");
                    Console.WriteLine(" dp - Doom PC Speaker.");
                    Console.WriteLine(" qplay - QBasic PLAY command argument (put directly in input path).");
                    Console.WriteLine("Output types:");
                    Console.WriteLine(" dro - DOSBox Raw OPL.");
                    Console.WriteLine(" droplay - DRO and plays it with 'dro_player' (needs to be available).");
                    Console.WriteLine(" beep - Plays using console beeps.");
                    Console.WriteLine(" wav - WAVE.");
                    Console.WriteLine(" play - Plays using WAVE.");
                    Console.WriteLine(" txt - simple RPC commands.");
                    Console.WriteLine(" dp - Doom PC Speaker.");
                    return(null);
                }
                else
                {
                    Error((errorArg != null && (errorArg.StartsWith("-") || errorArg.StartsWith("/"))?errorArg + ": ":"") + ex.Message + " Try --help.");
                }
            }

            return(options);
        }
Beispiel #21
0
 public abstract IList <OutputFile> ProcessStream(Stream input, ConvertOptions options);
Beispiel #22
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);
        }
Beispiel #23
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);
        }
Beispiel #24
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) });
        }
Beispiel #25
0
        public override IList <OutputFile> ProcessStream(Stream input, ConvertOptions options)
        {
            List <Command> commands = new List <Command>();
            int            linenum  = 0;

            using (StreamReader reader = new StreamReader(input))
            {
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    linenum += 1;
                    if (line.StartsWith("$"))
                    {
                        var match = Regex.Match(line, @"^\$(?<port>.+?)(:(?<state>.+?))?=(?<value>.+?)@(?<time>.+?)$");
                        if (match.Success)
                        {
                            int    port   = Convert.ToInt32(match.Groups["port"].Value, 16);
                            string sstate = match.Groups["state"].Value;
                            int    state  = String.IsNullOrEmpty(sstate)?-1:Convert.ToInt32(sstate, 16);
                            byte   value  = Convert.ToByte(match.Groups["value"].Value, 16);
                            int    time   = Convert.ToInt32(match.Groups["time"].Value);
                            switch (port)
                            {
                            case 0x42:
                                if (state == 3)
                                {
                                    commands.Add(new FrequencyByte1Command(value, time));
                                }
                                else if (state == 0)
                                {
                                    commands.Add(new FrequencyByte2Command(value, time));
                                }
                                else
                                {
                                    Program.Warning("{0}: Unknown port state ({1:x}).", linenum, state);
                                }
                                break;

                            case 0x43:
                                commands.Add(new FrequencyModeCommand((value & 0x0E) >> 1, time));
                                break;

                            case 0x61:
                                if (value != state)
                                {
                                    int diff = value ^ state;
                                    if (diff == 3)
                                    {
                                        commands.Add(new EnableCommand((value & 3) == 3, time));
                                    }
                                    else if (diff == 51)
                                    {
                                        commands.Add(new EnableCommand(false, time));
                                    }
                                }
                                break;

                            default:
                                Program.Warning("{0}: Undefined port {1:x}.", linenum, port);
                                break;
                            }
                        }
                        else
                        {
                            Program.Warning("{0}: Undefined line format.", linenum);
                        }
                    }
                }
            }

            return(ProcessRPC(ProcessPCS(commands, options), options));
        }
Beispiel #26
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);
        }