private CommandData ReadValue(TrackData Track, MmlFileReader m, CommandType Type) { var cmd = Track.AddCommand(Type); cmd.Value = ReadNumber(m); return(cmd); }
/// <summary> /// トラックコマンド読み出し /// </summary> private void ReadTrackText(string Name, MmlFileReader m) { var ct = SkipSpaceAndFetch(m); var TrackData = Song.GetTrack(Name); if (TrackData == null) { return; } bool Track = false; bool Block = false; // トラック if (ct == MmlCharactorType.GeneralChanacter) { Track = true; } if (ct == MmlCharactorType.BlockStart) { Block = true; Track = true; } if (Track) { if (Block) { m.SkipType(); } ReadCommandUntilNextTrack(TrackData, m, Block); return; } Error.Add(ErrorData.Type.UnknownCharacterUsed); }
// トラック private void ReadTrack(MmlFileReader m) { List <string> TrackName = new List <string>(); while (true) { var Name = m.ReadName(); TrackName.Add(Name); m.SkipIfSpace(); var ct = m.FetchType(); if (ct == MmlCharactorType.Separator) { m.SkipType(); continue; } break; } var TrackPos = m.GetPosition(); for (var i = 0; i < TrackName.Count; i++) { if (i > 0) { m.SetPosition(TrackPos); } var Name = TrackName[i]; VerboseWriteLine($"--- Track: {Name} ---"); ReadTrackText(Name, m); } }
// ブロック終了まで進める private void SkipUntilBlockEnd(MmlFileReader m) { while (true) { m.SkipSkipable(); var ct = m.FetchType(); if (ct == MmlCharactorType.GeneralChanacter || ct == MmlCharactorType.Separator) { VerboseWriteLine($"{m.GetPosition()} {ct}"); m.SkipType(); continue; } if (ct == MmlCharactorType.Eof) { Error.Add(ErrorData.Type.BlockEndNotFound); return; } if (ct == MmlCharactorType.BlockEnd) { m.SkipType(); m.StepNextLine(); return; } Error.Add(ErrorData.Type.UnknownCharacterUsed); return; } }
private CommandData ReadName(TrackData Track, MmlFileReader m, CommandType Type) { var cmd = Track.AddCommand(Type); var t = m.ReadName(); cmd.Text = t; return(cmd); }
// ヘッダ private void ReadHeader(MmlFileReader m) { var Pos = m.GetPosition(); m.StepNextCharacter(); var Name = m.ReadName(); VerboseWriteLine($"--- Header: {Name} {Pos} ---"); List <string> Parameter = new List <string>(); bool SkipSeparator = false; while (!m.IsEof()) { var ct = SkipSpaceAndFetch(m); if (m.IsLineEnd(ct)) { break; // 改行は終了 } if (SkipSeparator && m.IsSeparator(ct)) { ct = m.ReadNextType(); } if (m.IsSpace(ct)) { ct = m.ReadNextType(); } if (m.IsLineEnd(ct)) { break; // 改行は終了 } if (ct != MmlCharactorType.GeneralChanacter) { Error.Add(ErrorData.Type.UnknownCharacterUsed); return; } string t; if (m.IsQuote()) { t = m.ReadQuote(); if (t == null) { Error.Add(ErrorData.Type.QuoteEndNotFound); return; } } else { t = m.ReadUntilNext(); } SkipSeparator = true; Parameter.Add(t); } Header.Set(Song, Name, Parameter); }
private void Volume(SongData Song, TrackData Track, Command Command, MmlFileReader m) { var cmd = ReadValue(Track, m, CommandType.Volume); if (cmd.Value < 0 || Track.ChannelInfo.MaxVolume() < cmd.Value) { Error.Add(ErrorData.Type.VolumeIsWrong); } }
private void Rest(SongData Song, TrackData Track, Command Command, MmlFileReader m) { var cmd = Track.AddCommand(CommandType.Rest); Track.SetLastNote(cmd); var Tick = ReadNoteLength(Track.DefaultTick, Song.MasterTick, m); cmd.Tick = Tick; }
private void Tone(SongData Song, TrackData Track, Command Command, MmlFileReader m) { var cmd = ReadName(Track, m, CommandType.Tone); var tp = Song.GetToneParameter(cmd.Text); if (tp == null) { Error.Add(ErrorData.Type.ToneNameIsNotFound); cmd.Text = null; } }
// マクロ private void ReadMacro(MmlFileReader m) { // 位置を固定 var Pos = m.GetPosition(); m.StepNextCharacter(); var Name = m.ReadName(); VerboseWriteLine($"--- Macro: {Name} {Pos} ---"); ReadTrackText(Name, m); }
private int ReadParameter(MmlFileReader m) { var t = m.ReadNumber(); int result = 0; if (t == null || !int.TryParse(t, out result)) { Error.Add(ErrorData.Type.ParameterIsWrong); } return(result); }
// 音色を読み出す private int[] ReadToneParameter(MmlFileReader m) { List <int> Parameter = new List <int>(); bool SkipSeparator = false; while (true) { m.SkipSkipable(); var ct = m.FetchType(); // EOF if (ct == MmlCharactorType.Eof) { Error.Add(ErrorData.Type.BlockEndNotFound); return(null); } // Separator if (ct == MmlCharactorType.Separator) { VerboseWriteLine($"{m.GetPosition()} {ct}"); if (!SkipSeparator) { SkipSeparator = false; Parameter.Add(0); } m.SkipType(); continue; } if (m.IsLineEnd(ct) || m.IsComment(ct)) { m.SkipType(); continue; } if (ct == MmlCharactorType.GeneralChanacter) { SkipSeparator = true; VerboseWriteLine($"{m.GetPosition()} {ct}"); Parameter.Add(ReadParameter(m)); continue; } if (ct == MmlCharactorType.BlockEnd) { m.SkipType(); m.StepNextLine(); return(Parameter.ToArray()); } Error.Add(ErrorData.Type.UnknownCharacterUsed); return(null); } }
public void Make(SongData Song, TrackData Track, MmlFileReader m) { var fl = m.FetchLine(); var Command = ObjectList.FirstOrDefault(x => fl.StartsWith(x.Name)); if (Command == null) { Error.Add(ErrorData.Type.UnknownCommandName); return; } m.StepCount(Command.Name.Length); Command.Execute(Song, Track, Command, m); }
private void Tie(SongData Song, TrackData Track, Command Command, MmlFileReader m) { var cmd = Track.GetLastNote(); if (cmd == null) { Error.Add(ErrorData.Type.LastNoteNotFound); return; } var Tick = ReadNoteLength(Track.DefaultTick, Song.MasterTick, m); cmd.Tick += Tick; }
// ブロック開始まで進める private bool SkipUntilBlockStart(MmlFileReader m) { m.SkipSkipable(); var ct = m.FetchType(); if (ct != MmlCharactorType.BlockStart) { Error.Add(ErrorData.Type.BlockStartNotFound); return(false); } m.SkipType(); return(true); }
// エフェクト private void ReadEffect(MmlFileReader m) { // 位置を固定 var Pos = m.GetPosition(); m.StepNextCharacter(); var Name = m.ReadName(); VerboseWriteLine($"--- Effect: {Name} {Pos} ---"); if (!SkipUntilBlockStart(m)) { return; } SkipUntilBlockEnd(m); }
private int ReadNumber(MmlFileReader m, bool Required = true, int Default = 0) { var t = m.ReadNumber(); if (!Required) { return(Default); } int Result; if (t != null && int.TryParse(t, out Result)) { return(Result); } Error.Add(ErrorData.Type.InvalidNumber); return(Default); }
private void ParseMmlFile(string filename) { Song = new SongData(); Song.Error = Error; var m = new MmlFileReader(); Error.SetFileReader(m); if (!m.Load(filename)) { Error.Add(ErrorData.Type.FileNotFound); return; } while (!m.IsEof() && !Error.HasError) { // 行頭 var ct = m.FetchType(); // コメントブロック終了時の行は読み飛ばす if (ct == MmlCharactorType.CommentEnd) { m.SkipType(); m.StepNextLine(); } if (m.IsComment(ct)) { m.SkipType(); continue; } if (ct == MmlCharactorType.NextLine || ct == MmlCharactorType.Eof) { m.SkipType(); continue; } if (ct != MmlCharactorType.GeneralChanacter) { Error.Add(ErrorData.Type.LineHeaderIsWrong); continue; } ReadItem(m); } }
private void ReadItem(MmlFileReader m) { char ch = m.FetchCharacter(); switch (ch) { case '#': ReadHeader(m); break; case '%': ReadEffect(m); break; case '@': ReadTone(m); break; case '$': ReadMacro(m); break; default: ReadTrack(m); break; } }
// 音色 private void ReadTone(MmlFileReader m) { // 位置を固定 var Pos = m.GetPosition(); m.StepNextCharacter(); var Name = m.ReadName(); VerboseWriteLine($"--- Tone: {Name} {Pos} ---"); if (!SkipUntilBlockStart(m)) { return; } var Parameter = ReadToneParameter(m); Song.SetToneParameter(Name, Parameter); }
private int ReadNoteLength(int DefaultTick, int MasterTick, MmlFileReader m) { int Tick = DefaultTick; if (m.IsNextLine()) { return(Tick); } var ch = m.FetchCharacter(); if (ch == '%') { m.StepNextCharacter(); Tick = ReadNumber(m); } else { if (char.IsDigit(ch)) { int Len = ReadNumber(m, Default: -1); if (Len <= 0) { Error.Add(ErrorData.Type.NoteLengthIsWrong); } else { Tick = MasterTick / Len; } } ch = m.FetchCharacter(); int AddTick = Tick; while (ch == '.') { AddTick /= 2; Tick += AddTick; m.StepNextCharacter(); ch = m.FetchCharacter(); } } return(Tick); }
private void Note(SongData Song, TrackData Track, Command Command, MmlFileReader m) { var NoteNumber = NoteToNumber[Command.Name]; var cmd = Track.AddCommand(CommandType.Note); Track.SetLastNote(cmd); var ct = m.FetchType(); if (m.IsNextLine()) { cmd.Value = NoteNumber; cmd.Tick = Track.DefaultTick; return; } var ch = m.FetchCharacter(); bool Shift = false; if (ch == '-') { Shift = true; NoteNumber++; } if (ch == '+') { Shift = true; NoteNumber++; } if (Shift) { m.StepNextCharacter(); } cmd.Value = NoteNumber; var Tick = ReadNoteLength(Track.DefaultTick, Song.MasterTick, m); cmd.Tick = Tick; }
private void RelativeOctave(SongData Song, TrackData Track, Command Command, MmlFileReader m) { Track.AddCommand(Command.Name == ">" ? CommandType.OctaveGt : CommandType.OctaveLt); }
private void Macro(SongData Song, TrackData Track, Command Command, MmlFileReader m) { ReadName(Track, m, CommandType.Macro); }
private void Effect(SongData Song, TrackData Track, Command Command, MmlFileReader m) { ReadName(Track, m, CommandType.Effect); }
private void Length(SongData Song, TrackData Track, Command Command, MmlFileReader m) { var Tick = ReadNoteLength(Track.DefaultTick, Song.MasterTick, m); Track.DefaultTick = Tick; }
private void Tempo(SongData Song, TrackData Track, Command Command, MmlFileReader m) { ReadValue(Track, m, CommandType.Tempo); }
private void Octave(SongData Song, TrackData Track, Command Command, MmlFileReader m) { ReadValue(Track, m, CommandType.Octave); }
private void Staccato(SongData Song, TrackData Track, Command Command, MmlFileReader m) { var cmd = Track.AddCommand(CommandType.Staccato); cmd.Value = ReadNumber(m); }
private void Slur(SongData Song, TrackData Track, Command Command, MmlFileReader m) { var cmd = Track.AddCommand(CommandType.Slur); cmd.Value = 1; }