static int Main(string[] args) { Log.writeLine += WriteLine; #if DEBUG //Log.writeLine += WriteLineF; Log.level = LogLevel.INFO; #else Log.level = LogLevel.INFO; #endif int fnIndex = AnalyzeOption(args); int mIndex = -1; if (args != null) { for (int i = fnIndex; i < args.Length; i++) { if ((Path.GetExtension(args[i]).ToUpper().IndexOf(".M") < 0) && (Path.GetExtension(args[i]).ToUpper().IndexOf(".XML") < 0) ) { continue; } mIndex = i; break; } } if (mIndex < 0) { Log.WriteLine(LogLevel.INFO, "引数(.Mファイル)1個欲しいよぉ..."); return(-1); } srcFile = args[mIndex]; if (!File.Exists(args[mIndex])) { Log.WriteLine(LogLevel.ERROR, string.Format("ファイル[{0}]が見つかりません", args[mIndex])); return(-1); } rsc = CheckDevice(); try { SineWaveProvider16 waveProvider; int latency = 1000; switch (device) { case 0: waveProvider = new SineWaveProvider16(); waveProvider.SetWaveFormat((int)SamplingRate, 2); callBack = EmuCallback; audioOutput = new DirectSoundOut(latency); audioOutput.Init(waveProvider); break; case 1: case 2: trdMain = new Thread(new ThreadStart(RealCallback)); trdMain.Priority = ThreadPriority.Highest; trdMain.IsBackground = true; trdMain.Name = "trdVgmReal"; sw = Stopwatch.StartNew(); swFreq = Stopwatch.Frequency; break; } MDSound.ym2608 ym2608 = new MDSound.ym2608(); MDSound.MDSound.Chip chip = new MDSound.MDSound.Chip { type = MDSound.MDSound.enmInstrumentType.YM2608, ID = 0, Instrument = ym2608, Update = ym2608.Update, Start = ym2608.Start, Stop = ym2608.Stop, Reset = ym2608.Reset, SamplingRate = SamplingRate, Clock = opnaMasterClock, Volume = 0, Option = new object[] { GetApplicationFolder() } }; ppz8em = new MDSound.PPZ8(); MDSound.MDSound.Chip chipp = new MDSound.MDSound.Chip { type = MDSound.MDSound.enmInstrumentType.PPZ8, ID = 0, Instrument = ppz8em, Update = ppz8em.Update, Start = ppz8em.Start, Stop = ppz8em.Stop, Reset = ppz8em.Reset, SamplingRate = SamplingRate, Clock = opnaMasterClock, Volume = 0, Option = null }; ppsdrv = new MDSound.PPSDRV(); MDSound.MDSound.Chip chipps = new MDSound.MDSound.Chip { type = MDSound.MDSound.enmInstrumentType.PPSDRV, ID = 0, Instrument = ppsdrv, Update = ppsdrv.Update, Start = ppsdrv.Start, Stop = ppsdrv.Stop, Reset = ppsdrv.Reset, SamplingRate = (uint) ( device == 0 ? SamplingRate : ( userPPSFREQ == -1 ? ( device == 1 ? SamplingRatePPSGIMIC : SamplingRatePPSSCCI ) : (uint)userPPSFREQ ) ), Clock = opnaMasterClock, Volume = 0, Option = device == 0 ? null : (new object[] { (Action <int, int>)PPSDRVpsg }) }; p86em = new MDSound.P86(); MDSound.MDSound.Chip chip86 = new MDSound.MDSound.Chip { type = MDSound.MDSound.enmInstrumentType.mpcmX68k,//TBD ID = 0, Instrument = p86em, Update = p86em.Update, Start = p86em.Start, Stop = p86em.Stop, Reset = p86em.Reset, SamplingRate = SamplingRate, Clock = opnaMasterClock, Volume = 0, Option = null }; mds = new MDSound.MDSound(SamplingRate, samplingBuffer, new MDSound.MDSound.Chip[] { chip, chipp, chipps, chip86 }); //ppz8em = new PPZ8em(SamplingRate); //ppsdrv = new PPSDRV(SamplingRate); Common.Environment env = new Common.Environment(); env.AddEnv("pmd"); env.AddEnv("pmdopt"); envPmd = env.GetEnvVal("pmd"); envPmdOpt = env.GetEnvVal("pmdopt"); List <string> opt = (envPmdOpt == null) ? (new List <string>()) : envPmdOpt.ToList(); for (int i = fnIndex; i < args.Length; i++) { opt.Add(args[i]); } mIndex += (envPmdOpt == null ? 0 : envPmdOpt.Length) - fnIndex; #if NETCOREAPP System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance); #endif drv = new Driver.Driver(); Driver.PMDDotNETOption dop = new Driver.PMDDotNETOption(); dop.isAUTO = isAUTO; dop.isNRM = isNRM; dop.isSPB = isSPB; dop.isVA = isVA; dop.usePPS = usePPS; dop.usePPZ = usePPZ; dop.isLoadADPCM = false; dop.loadADPCMOnly = false; //dop.ppz8em = ppz8em; //dop.ppsdrv = ppsdrv; dop.envPmd = envPmd; dop.srcFile = srcFile; dop.jumpIndex = -1;// -1; List <string> pop = new List <string>(); bool pmdvolFound = false; for (int i = 0; i < opt.Count; i++) { if (i == mIndex) { continue; } string op = opt[i].ToUpper().Trim(); pop.Add(op); if (op.IndexOf("-D") >= 0 || op.IndexOf("/D") >= 0) { pmdvolFound = true; } } Log.WriteLine(LogLevel.INFO, ""); ((Driver.Driver)drv).Init( srcFile , OPNAWrite , OPNAWaitSend , dop , pop.ToArray() , appendFileReaderCallback , PPZ8Write , PPSDRVWrite , P86Write ); //AUTO指定の場合に構成が変わるので、構成情報を受け取ってから音量設定を行う isNRM = dop.isNRM; isSPB = dop.isSPB; isVA = dop.isVA; usePPS = dop.usePPS; usePPZ = dop.usePPZ; string[] pmdOptionVol = SetVolume(); //ユーザーがコマンドラインでDオプションを指定していない場合はpmdVolを適用させる if (!pmdvolFound && pmdOptionVol != null && pmdOptionVol.Length > 0) { ((Driver.Driver)drv).resetOption(pmdOptionVol);// } List <Tuple <string, string> > tags = drv.GetTags(); if (tags != null) { foreach (Tuple <string, string> tag in tags) { if (tag.Item1 == "") { continue; } WriteLine2(LogLevel.INFO, string.Format("{0,-16} : {1}", tag.Item1, tag.Item2), 16 + 3); } } Log.WriteLine(LogLevel.INFO, ""); drv.StartRendering((int)SamplingRate , new Tuple <string, int>[] { new Tuple <string, int>("YM2608", (int)opnaMasterClock) }); drv.MusicSTART(0); switch (device) { case 0: audioOutput.Play(); break; case 1: case 2: trdMain.Start(); break; } Log.WriteLine(LogLevel.INFO, "演奏を終了する場合は何かキーを押してください(実chip時は特に。)"); while (true) { System.Threading.Thread.Sleep(1); if (Console.KeyAvailable) { break; } //ステータスが0(終了)又は0未満(エラー)の場合はループを抜けて終了 if (drv.GetStatus() <= 0) { if (drv.GetStatus() == 0) { System.Threading.Thread.Sleep((int)(latency * 2.0));//実際の音声が発音しきるまでlatency*2の分だけ待つ } break; } if (loop != 0 && drv.GetNowLoopCounter() > loop) { System.Threading.Thread.Sleep((int)(latency * 2.0));//実際の音声が発音しきるまでlatency*2の分だけ待つ break; } } drv.MusicSTOP(); drv.StopRendering(); ((Driver.Driver)drv).dispStatus(); } catch (PmdException pe) { Log.WriteLine(LogLevel.ERROR, pe.Message); } catch (Exception ex) { Log.WriteLine(LogLevel.FATAL, "演奏失敗"); Log.WriteLine(LogLevel.FATAL, string.Format("message:{0}", ex.Message)); Log.WriteLine(LogLevel.FATAL, string.Format("stackTrace:{0}", ex.StackTrace)); } finally { if (((Driver.Driver)drv).renderingException != null) { Log.WriteLine(LogLevel.FATAL, "演奏失敗"); Log.WriteLine(LogLevel.FATAL, string.Format("message:{0}", ((Driver.Driver)drv).renderingException.Message)); Log.WriteLine(LogLevel.FATAL, string.Format("stackTrace:{0}", ((Driver.Driver)drv).renderingException.StackTrace)); } if (audioOutput != null) { audioOutput.Stop(); while (audioOutput.PlaybackState == PlaybackState.Playing) { Thread.Sleep(1); } audioOutput.Dispose(); audioOutput = null; } if (trdMain != null) { trdClosed = true; while (!trdStopped) { Thread.Sleep(1); } } if (nc86ctl != null) { nc86ctl.deinitialize(); nc86ctl = null; } if (nScci != null) { nScci.Dispose(); nScci = null; } } return(0); }
private static void Compile(string[] args, int argIndex) { try { //mc向け引数のリストを作る List <string> lstMcArg = new List <string>(); for (int i = argIndex; i < args.Length; i++) { lstMcArg.Add(args[i]); } Compiler.Compiler compiler = new Compiler.Compiler(); compiler.Init(); compiler.mcArgs = lstMcArg.ToArray(); env = new Common.Environment(); env.AddEnv("arranger"); env.AddEnv("composer"); env.AddEnv("user"); env.AddEnv("mcopt"); env.AddEnv("pmd"); compiler.env = env.GetEnv(); //各種ファイルネームを得る int s = 0; foreach (string arg in compiler.mcArgs) { if (string.IsNullOrEmpty(arg)) { continue; } if (arg[0] == '-' || arg[0] == '/') { continue; } if (s == 0) { srcFile = arg; } else if (s == 1) { ffFile = arg; } else if (s == 2) { desFile = arg; } s++; } if (string.IsNullOrEmpty(srcFile)) { Log.WriteLine(LogLevel.ERROR, msg.get("E0601")); return; } byte[] ffFileBuf = null; if (!string.IsNullOrEmpty(ffFile) && File.Exists(ffFile)) { ffFileBuf = File.ReadAllBytes(ffFile); compiler.SetFfFileBuf(ffFileBuf); } #if DEBUG compiler.SetCompileSwitch("IDE"); //compiler.SetCompileSwitch("SkipPoint=R17:C18"); #endif if (!isXml) { //デフォルトはソースファイル名の拡張子を.Mに変更したものにする string destFileName = ""; if (!string.IsNullOrEmpty(srcFile)) { destFileName = Path.Combine(Path.GetDirectoryName(Path.GetFullPath(srcFile)), string.Format("{0}.M", Path.GetFileNameWithoutExtension(srcFile))); } //TagからFilenameを得る string srcText; using (FileStream sourceMML = new FileStream(srcFile, FileMode.Open, FileAccess.Read, FileShare.Read)) using (StreamReader sr = new StreamReader(sourceMML, Encoding.GetEncoding("Shift_JIS"))) srcText = sr.ReadToEnd(); string outFileName = ""; Tuple <string, string>[] tags = compiler.GetTags(srcText, appendFileReaderCallback); if (tags != null && tags.Length > 0) { foreach (Tuple <string, string> tag in tags) { #if DEBUG Log.WriteLine(LogLevel.TRACE, string.Format("{0}\t: {1}", tag.Item1, tag.Item2)); #endif //出力ファイル名を得る if (tag.Item1.ToUpper().IndexOf("#FI") != 0) { continue; //mcは3文字まで判定している為 } outFileName = tag.Item2; } } //TagにFileName指定がある場合はそちらを適用する if (!string.IsNullOrEmpty(outFileName)) { if (outFileName[0] != '.') { //ファイル名指定の場合 destFileName = Path.Combine( Path.GetDirectoryName(Path.GetFullPath(srcFile)) , outFileName); } else { //拡張子のみの指定の場合 destFileName = Path.Combine( Path.GetDirectoryName(Path.GetFullPath(srcFile)) , string.Format("{0}{1}" , Path.GetFileNameWithoutExtension(srcFile) , outFileName)); } } //最終的にdesFileの指定がある場合は、そちらを優先する if (desFile != null) { destFileName = desFile; } bool isSuccess = false; using (FileStream sourceMML = new FileStream(srcFile, FileMode.Open, FileAccess.Read, FileShare.Read)) //using (FileStream destCompiledBin = new FileStream(destFileName, FileMode.Create, FileAccess.Write)) using (MemoryStream destCompiledBin = new MemoryStream()) using (Stream bufferedDestStream = new BufferedStream(destCompiledBin)) { isSuccess = compiler.Compile(sourceMML, bufferedDestStream, appendFileReaderCallback); if (isSuccess) { bufferedDestStream.Flush(); byte[] destbuf = destCompiledBin.ToArray(); File.WriteAllBytes(destFileName, destbuf); if (compiler.outFFFileBuf != null) { string outfn = Path.Combine(Path.GetDirectoryName(destFileName), compiler.outFFFileName); File.WriteAllBytes(outfn, compiler.outFFFileBuf); } } } } else { string destFileName = Path.Combine(Path.GetDirectoryName(Path.GetFullPath(srcFile)), string.Format("{0}.xml", Path.GetFileNameWithoutExtension(srcFile))); if (desFile != null) { destFileName = desFile; } MmlDatum[] dest = null; //xmlの時はIDEモードでコンパイル compiler.SetCompileSwitch("IDE"); using (FileStream sourceMML = new FileStream(srcFile, FileMode.Open, FileAccess.Read, FileShare.Read)) { dest = compiler.Compile(sourceMML, appendFileReaderCallback); } XmlSerializer serializer = new XmlSerializer(typeof(MmlDatum[]), typeof(MmlDatum[]).GetNestedTypes()); using (StreamWriter sw = new StreamWriter(destFileName, false, Encoding.UTF8)) { serializer.Serialize(sw, dest); } } } catch (Exception ex) { Log.WriteLine(LogLevel.FATAL, ex.Message); Log.WriteLine(LogLevel.FATAL, ex.StackTrace); } finally { } }