Ejemplo n.º 1
0
        static int Main(string[] args)
        {
            Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-us");
            Thread.CurrentThread.CurrentCulture   = new System.Globalization.CultureInfo("en-us");
            Console.OutputEncoding       = System.Text.Encoding.UTF8;
            Console.TreatControlCAsInput = true;

            string infile = "", outfile = "";
            int    blockSize        = 100;
            short  SilenceThreshold = 4;
            bool   enableDithering  = true;
            bool   enc = false;

            int    oldCurTop           = 0;
            string titleAndVersionInfo = "";

            Compression.Algorithm compression = Compression.Algorithm.fast;

            #region Parse Parameters
            //Check for parameter for the analysis and output a JSON string into the console
            int  i;
            bool analyze = false;
            for (i = 0; i < args.Length; i++)
            {
                if (args[i] == "-ajson" || args[i] == "-a")
                {
                    analyze = true;
                }
            }

            if (!analyze)
            {
                Console.CursorVisible = true;
                Console.CursorSize    = 100;
                Console.Title         = "BPCM";

                Assembly assembly             = Assembly.GetExecutingAssembly();
                var      descriptionAttribute = assembly
                                                .GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false)
                                                .OfType <AssemblyDescriptionAttribute>()
                                                .FirstOrDefault();

                titleAndVersionInfo = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name.ToUpper() + ": " + descriptionAttribute.Description + " version " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString() + " \"Feline\"";
                Console.WriteLine("");
                oldCurTop = Console.CursorTop;
                Console.WriteLine(titleAndVersionInfo);
                Console.WriteLine(String.Concat(Enumerable.Repeat("\x2550", 80)));
                if (args?.Length == 0)
                {
                    return(printUsage());
                }
            }

            //Check for input file and then check the type
            //BPCM (decode)
            int bpcm = int.MaxValue;
            int wave = int.MaxValue;
            for (i = 0; i < args.Length; i++)
            {
                if (File.Exists(args[i]) && (Path.GetExtension(args[i]).ToLower() == ".bpcm" || Path.GetExtension(args[i]).ToLower() == ".bpcm2"))
                {
                    enc    = false;
                    bpcm   = i;
                    infile = args[i];
                }
            }

            //WAVE (encode)
            for (i = 0; i < args.Length; i++)
            {
                if (File.Exists(args[i]) && Path.GetExtension(args[i]).ToLower() == ".wav" && i < bpcm)
                {
                    enc    = true;
                    wave   = i;
                    infile = args[i];
                }
            }

            for (i = 0; i < args.Length; i++)
            {
                //Check for output file
                if ((Path.GetExtension(args[i]) == ".bpcm" || Path.GetExtension(args[i]).ToLower() == ".bpcm2") && i > wave)
                {
                    outfile = args[i];
                }

                if (Path.GetExtension(args[i]) == ".wav" && i > bpcm)
                {
                    outfile = args[i];
                }
            }

            if (!enc)
            {
                //Extra parameters
                for (i = 0; i < args.Length; i++)
                {
                    if (args[i] == "-nodither")
                    {
                        enableDithering = false;
                    }
                }
            }

            //If no output file was not given, launch player mode
            if (outfile == "" && infile != "" && (Path.GetExtension(infile).ToLower() == ".bpcm" || Path.GetExtension(infile).ToLower() == ".bpcm2"))
            {
                if (analyze)
                {
                    Decoder.Info inf  = Decoder.AnalyzeFile(infile);
                    string       JSON =
                        "{\"SamplingRate\":" + inf.SamplingRate + ","
                        + "\"NumberOfChannels\":" + inf.NumberOfChannels + ","
                        + "\"BitrateAvg\":" + inf.BitrateAvg + ","
                        + "\"BitrateMin\":" + inf.BitrateMin + ","
                        + "\"BitrateMax\":" + inf.BitrateMax + ","
                        + "\"BlockSizeNominal\":" + inf.BlockSizeNominal + ","
                        + "\"BlockSizeAverage\":" + inf.BlockSizeAverage + ","
                        + "\"BlockSizeMinimum\":" + inf.BlockSizeMinimum + ","
                        + "\"BlockSizeMaximum\":" + inf.BlockSizeMaximum + ","
                        + "\"CompressionUsedString\":\"" + inf.CompressionUsedString + "\","
                        + "\"Duration\":" + inf.Duration.ToString() + ","
                        + "\"DurationSampleCount\":" + inf.DurationSampleCount + ","
                        + "\"DurationString\":\"" + inf.DurationString + "\","
                        + "\"FrameCount\":" + inf.FrameSet.Count + ","
                        + "\"Frames\":{";
                    foreach (Frame f in inf.FrameSet)
                    {
                        JSON = string.Concat(new string[] {
                            JSON, "\"", f.FrameNumber.ToString(), "\":"
                            , "{\"Channels\":", f.Channels.ToString(), ","
                            , "\"CompressionType\":\"", f.CompressionTypeDescr, "\","
                            , "\"DataLength\":", f.DataLength.ToString(), ","
                            , "\"DataOffset\":", f.DataOffset.ToString(), ","
                            , "\"SampleCount\":", f.SampleCount.ToString(), ","
                            , "\"Duration\":", f.Duration.ToString(), ","
                            , "\"HederLength\":", f.HederLength.ToString(), ","
                            , "\"TimeStamp\":", f.TimeStamp.ToString(), "},"
                        });
                    }
                    JSON = JSON.Substring(0, JSON.Length - 1);
                    JSON = JSON + "},\"FrameLengthHistogram\":{";
                    foreach (KeyValuePair <int, long> p in inf.FrameSampleCountHistogram)
                    {
                        JSON = string.Concat(new string[] { JSON, "\"", p.Key.ToString(), "\":", p.Value.ToString(), "," });
                    }
                    JSON = JSON.Substring(0, JSON.Length - 1);
                    JSON = JSON + "}}";
                    Console.Write(JSON);
                    return(0);
                }

                float  vol           = 0.12f;
                double rate          = 1;
                int    output_device = 0;

                //Check for parameters
                for (i = 0; i < args.Length; i++)
                {
                    if (args[i] == "-vol" && i != args.Length - 1) //Volume parameter
                    {
                        if (!float.TryParse(args[i + 1], out vol))
                        {
                            return(printUsage());
                        }
                    }
                    if (args[i] == "-r" && i != args.Length - 1) //Playback rate parameter
                    {
                        if (!double.TryParse(args[i + 1], out rate))
                        {
                            return(printUsage());
                        }
                    }
                    if (args[i] == "-od" && i != args.Length - 1) //Output device parameter
                    {
                        if (!int.TryParse(args[i + 1], out output_device))
                        {
                            return(printUsage());
                        }
                    }
                }

                play(infile, (float)vol, rate, output_device, enableDithering);
                return(0);
            }

            //When we are in encoding mode, check for parameters
            if (enc)
            {
                //Compression algorithm
                for (i = 0; i < args.Length; i++)
                {
                    if (args[i] == "-c" && i != args.Length - 1)
                    {
                        switch (args[i + 1].ToLower())
                        {
                        case "none":
                            compression = Compression.Algorithm.none;
                            break;

                        case "bzip2":
                            compression = Compression.Algorithm.BZIP2;
                            break;

                        case "lzma":
                            compression = Compression.Algorithm.lzma;
                            break;

                        case "ac":
                            compression = Compression.Algorithm.arithmetic;
                            break;

                        case "fast":
                            compression = Compression.Algorithm.fast;
                            break;

                        case "brute":
                        case "bruteforce":
                            compression = Compression.Algorithm.bruteForce;
                            break;
                        }
                    }
                }

                //Block size
                for (i = 0; i < args.Length; i++)
                {
                    if (args[i] == "-bs" && i != args.Length - 1)
                    {
                        if (!int.TryParse(args[i + 1], out blockSize))
                        {
                            return(printUsage());
                        }
                    }
                }

                //Fix block size
                if (blockSize < 10)
                {
                    blockSize = 10;
                }
                if (blockSize > 1000)
                {
                    blockSize = 1000;
                }

                //Extra parameters
                for (i = 0; i < args.Length; i++)
                {
                    if (args[i] == "-sltrh" && i != args.Length - 1)
                    {
                        if (!short.TryParse(args[i + 1], out SilenceThreshold))
                        {
                            return(printUsage());
                        }
                    }
                }
            }
            #endregion ;

            if (infile == "" || outfile == "")
            {
                return(printUsage());
            }

            TimeSpan e_start;

            //check wether encoding or decoding is requested
            if (enc)
            {
                Console.WriteLine("Encoding file:         " + infile);
                Console.WriteLine("to:                    " + outfile);
                Console.WriteLine("with block size:       " + blockSize.ToString());
                Console.WriteLine("Compression algorithm: " + compression.ToString());
                Console.WriteLine("SilenceThreshold:      " + SilenceThreshold.ToString());
                Console.WriteLine(String.Concat(Enumerable.Repeat("\x2509", 80)));

                e_start = TimeSpan.FromTicks(DateTime.Now.Ticks);

                try {
                    Encoder.EncodeWaveFile(
                        infile
                        , outfile, new Encoder.Parameters()
                    {
                        BlockSize          = blockSize
                        , Compression      = compression
                        , SilenceThreshold = SilenceThreshold
                    }
                        , updateStatus
                        , 1000 / 7.5
                        );
                } catch (Exception e) {
                    Console.WriteLine("Error: " + e.Message);
                    return(127);
                }

                void updateStatus(Encoder.Status stts)
                {
                    string progress = "Encoding: " + stts.PositionString + " ("
                                      + ((double)stts.PositionSamples / stts.DurationSamples * 100).ToString("F2")
                                      + "%) at average " + String.Format("{0:0 bits/s}", stts.AvgBitrate) + " at "
                                      + String.Format("{0:0.000}x speed.", stts.Position / (TimeSpan.FromTicks(DateTime.Now.Ticks) - e_start).TotalSeconds);

                    Console.Write(progress.PadRight(Console.WindowWidth - 1, Convert.ToChar(" ")));
                    Console.CursorLeft = 0;
                }
            }
            else
            {
                e_start = TimeSpan.FromTicks(DateTime.Now.Ticks);
                Decoder.DecodeBPCMFile(infile, outfile, updateStatus, 1000 / 7.5, true, initialized, enableDithering);

                void initialized(Decoder.Info inf)
                {
                    Console.WriteLine("{0,-20} {1}", "Filename:", infile);
                    Console.WriteLine("{0,-20} {1}", "to:", outfile);
                    Console.WriteLine("{0,-20} {1}", "File size:", Helpers.ByteFormatter.FormatBytes(new FileInfo(infile).Length));
                    printInfo(inf);
                    Console.WriteLine(String.Concat(Enumerable.Repeat("\x2509", 80)));
                }

                void updateStatus(Decoder.Status stts)
                {
                    Console.Write(("Decoding: " + stts.PositionString + " (" + stts.PercentageDone.ToString("F2") + "%)"
                                   + " at " + String.Format("{0:0.000}x speed.", stts.Position / (TimeSpan.FromTicks(DateTime.Now.Ticks) - e_start).TotalSeconds)).PadRight(Console.WindowWidth - 1, Convert.ToChar(" ")));
                    Console.CursorLeft = 0;
                }
            }

            return(0);
        }