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); }