コード例 #1
0
        private static LinkedList <LilypondToken> GetTokensFromLilypond(string content)
        {
            var tokens = new LinkedList <LilypondToken>();

            foreach (string s in content.Split(' ').Where(item => item.Length > 0))
            {
                LilypondToken token = new LilypondToken()
                {
                    Value = s
                };

                //token = CheckTokenKind(s, token);
                //token = CheckTokenKindIsNote(s, token);
                token.TokenKind = new LilypondTokenFactory(s).getTokenKind();

                if (tokens.Last != null)
                {
                    tokens.Last.Value.NextToken = token;
                    token.PreviousToken         = tokens.Last.Value;
                }

                tokens.AddLast(token);
            }

            return(tokens);
        }
コード例 #2
0
        public void Solve(LilypondContext context, LilypondToken token)
        {
            token = token.NextToken;
            var times         = token.Value.Split('/');
            var timeSignature = new PSAMControlLibrary.TimeSignature(TimeSignatureType.Numbers, UInt32.Parse(times[0]), UInt32.Parse(times[1]));

            context.Symbols.Add(timeSignature);
        }
コード例 #3
0
        private LinkedList <LilypondToken> getTokensFromLilypond(string lilyPondText)
        {
            var tokens = new LinkedList <LilypondToken>();

            foreach (string substring in lilyPondText.Split(' ').Where(item => item.Length > 0))
            {
                var           sanitizedString = substring.Replace("\r\n", string.Empty);
                LilypondToken token           = new LilypondToken
                {
                    Value = sanitizedString
                };

                switch (sanitizedString)
                {
                case "\\relative": token.TokenKind = LilypondTokenKind.Staff; break;

                case "\\clef": token.TokenKind = LilypondTokenKind.Clef; break;

                case "\\time": token.TokenKind = LilypondTokenKind.Time; break;

                case "\\tempo": token.TokenKind = LilypondTokenKind.Tempo; break;

                case "\\repeat": token.TokenKind = LilypondTokenKind.Repeat; break;

                case "\\alternative": token.TokenKind = LilypondTokenKind.Alternative; break;

                case "{": token.TokenKind = LilypondTokenKind.SectionStart; break;

                case "}": token.TokenKind = LilypondTokenKind.SectionEnd; break;

                case "|": token.TokenKind = LilypondTokenKind.Bar; break;

                default: token.TokenKind = LilypondTokenKind.Unknown; break;
                }

                switch (token.TokenKind)
                {
                case LilypondTokenKind.Unknown when new Regex(@"[a-g][,'eis]*[0-9]+[~]?[.]*", RegexOptions.IgnoreCase).IsMatch(token.Value):
                    token.TokenKind = LilypondTokenKind.Note;
                    break;

                case LilypondTokenKind.Unknown when new Regex(@"r.*?[0-9][.]*").IsMatch(substring):
                    token.TokenKind = LilypondTokenKind.Rest;
                    break;
                }

                if (tokens.Last != null)
                {
                    tokens.Last.Value.NextToken = token;
                    token.PreviousToken         = tokens.Last.Value;
                }

                tokens.AddLast(token);
            }

            return(tokens);
        }
コード例 #4
0
        private static LinkedList <LilypondToken> GetTokensFromLilypond(string content)
        {
            var tokens = new LinkedList <LilypondToken>();

            foreach (string s in content.Split(' ').Where(item => item.Length > 0))
            {
                LilypondToken token = new LilypondToken()
                {
                    Value = s
                };

                switch (s)
                {
                case "\\relative": token.TokenKind = LilypondTokenKind.Staff; break;

                case "\\clef": token.TokenKind = LilypondTokenKind.Clef; break;

                case "\\time": token.TokenKind = LilypondTokenKind.Time; break;

                case "\\tempo": token.TokenKind = LilypondTokenKind.Tempo; break;

                case "\\repeat": token.TokenKind = LilypondTokenKind.Repeat; break;

                case "\\alternative": token.TokenKind = LilypondTokenKind.Alternative; break;

                case "{": token.TokenKind = LilypondTokenKind.SectionStart; break;

                case "}": token.TokenKind = LilypondTokenKind.SectionEnd; break;

                case "|": token.TokenKind = LilypondTokenKind.Bar; break;

                default: token.TokenKind = LilypondTokenKind.Unknown; break;
                }

                if (token.TokenKind == LilypondTokenKind.Unknown && new Regex(@"[~]?[a-g][,'eis]*[0-9]+[.]*").IsMatch(s))
                {
                    token.TokenKind = LilypondTokenKind.Note;
                }
                else if (token.TokenKind == LilypondTokenKind.Unknown && new Regex(@"r.*?[0-9][.]*").IsMatch(s))
                {
                    token.TokenKind = LilypondTokenKind.Rest;
                }

                if (tokens.Last != null)
                {
                    tokens.Last.Value.NextToken = token;
                    token.PreviousToken         = tokens.Last.Value;
                }

                tokens.AddLast(token);
            }

            return(tokens);
        }
コード例 #5
0
        public void Solve(LilypondContext context, LilypondToken token)
        {
            // Length
            int noteLength = Int32.Parse(Regex.Match(token.Value, @"\d+").Value);
            // Crosses and Moles
            int alter = 0;

            alter += Regex.Matches(token.Value, "is").Count;
            alter -= Regex.Matches(token.Value, "es|as").Count;
            // Octaves
            int distanceWithPreviousNote = notesorder.IndexOf(token.Value[0]) - notesorder.IndexOf(context.PreviousNote);

            if (distanceWithPreviousNote > 3)  // Shorter path possible the other way around
            {
                distanceWithPreviousNote -= 7; // The number of notes in an octave
            }
            else if (distanceWithPreviousNote < -3)
            {
                distanceWithPreviousNote += 7; // The number of notes in an octave
            }

            if (distanceWithPreviousNote + notesorder.IndexOf(context.PreviousNote) >= 7)
            {
                context.PreviousOctave++;
            }
            else if (distanceWithPreviousNote + notesorder.IndexOf(context.PreviousNote) < 0)
            {
                context.PreviousOctave--;
            }

            // Force up or down.
            context.PreviousOctave += token.Value.Count(c => c == '\'');
            context.PreviousOctave -= token.Value.Count(c => c == ',');

            context.PreviousNote = token.Value[0];

            var note = new Note(token.Value[0].ToString().ToUpper(), alter, context.PreviousOctave, (MusicalSymbolDuration)noteLength, NoteStemDirection.Up, NoteTieType.None, new List <NoteBeamType>()
            {
                NoteBeamType.Single
            });

            note.NumberOfDots += token.Value.Count(c => c.Equals('.'));

            context.Symbols.Add(note);
        }
コード例 #6
0
        public IEnumerable <MusicalSymbol> Solve()
        {
            LilypondToken currentToken = tokens.First?.Value;

            while (currentToken != null)
            {
                var handler = new ExpressionFactory().Get(currentToken.TokenKind.ToString());

                if (handler != null)
                {
                    handler.Solve(context, currentToken);
                }

                currentToken = currentToken.NextToken;
            }

            return(context.Symbols);
        }
コード例 #7
0
        public LilypondToken Tokenize(string s)
        {
            var token = new LilypondToken()
            {
                Value = s
            };

            foreach (var handler in handlers)
            {
                if (handler.canHandle(s))
                {
                    token.TokenKind = handler.handle(s);
                    return(token);
                }
            }

            return(token); // never reached, but it's needed for the compiler.
        }
コード例 #8
0
        public void Solve(LilypondContext context, LilypondToken token)
        {
            token = token.NextToken;

            if (token == null)
            {
                return;
            }

            if (token.Value == "treble")
            {
                context.CurrentClef = new PSAMControlLibrary.Clef(ClefType.GClef, 2);
            }
            else if (token.Value == "bass")
            {
                context.CurrentClef = new PSAMControlLibrary.Clef(ClefType.FClef, 4);
            }
            //else
            //    throw new NotSupportedException($"Clef {token.Value} is not supported.");

            context.Symbols.Add(context.CurrentClef);
        }
コード例 #9
0
        private static LinkedList <LilypondToken> GetTokensFromLilypond(string content)
        {
            var tokens    = new LinkedList <LilypondToken>();
            var tokenizer = new Tokenizer();

            content = content.Trim().ToLower().Replace("\r\n", " ").Replace("\n", " ").Replace("  ", " ");

            foreach (string s in content.Split(' '))
            {
                LilypondToken token = tokenizer.Tokenize(s);

                if (tokens.Last != null)
                {
                    tokens.Last.Value.NextToken = token;
                    token.PreviousToken         = tokens.Last.Value;
                }

                tokens.AddLast(token);
            }

            return(tokens);
        }
コード例 #10
0
ファイル: MusicLoader.cs プロジェクト: Bryans91/MusicReader
        private static IEnumerable <MusicalSymbol> GetStaffsFromTokens(LinkedList <LilypondToken> tokens)
        {
            List <MusicalSymbol> symbols = new List <MusicalSymbol>();

            Clef currentClef             = null;
            int  previousOctave          = 4;
            char previousNote            = 'c';
            bool inRepeat                = false;
            bool inAlternative           = false;
            int  alternativeRepeatNumber = 0;

            LilypondToken currentToken = tokens.First();

            while (currentToken != null)
            {
                // TODO: There are a lot of switches based on LilypondTokenKind, can't those be eliminated en delegated?
                // HINT: Command, Decorator, Factory etc.

                // TODO: Repeats are somewhat weirdly done. Can we replace this with the COMPOSITE pattern?
                switch (currentToken.TokenKind)
                {
                case LilypondTokenKind.Unknown:
                    break;

                case LilypondTokenKind.Repeat:
                    inRepeat = true;
                    symbols.Add(new Barline()
                    {
                        RepeatSign = RepeatSignType.Forward
                    });
                    break;

                case LilypondTokenKind.SectionEnd:
                    if (inRepeat && currentToken.NextToken?.TokenKind != LilypondTokenKind.Alternative)
                    {
                        inRepeat = false;
                        symbols.Add(new Barline()
                        {
                            RepeatSign = RepeatSignType.Backward, AlternateRepeatGroup = alternativeRepeatNumber
                        });
                    }
                    else if (inAlternative && alternativeRepeatNumber == 1)
                    {
                        alternativeRepeatNumber++;
                        symbols.Add(new Barline()
                        {
                            RepeatSign = RepeatSignType.Backward, AlternateRepeatGroup = alternativeRepeatNumber
                        });
                    }
                    else if (inAlternative && currentToken.NextToken.TokenKind == LilypondTokenKind.SectionEnd)
                    {
                        inAlternative           = false;
                        alternativeRepeatNumber = 0;
                    }
                    break;

                case LilypondTokenKind.SectionStart:
                    if (inAlternative && currentToken.PreviousToken.TokenKind != LilypondTokenKind.SectionEnd)
                    {
                        alternativeRepeatNumber++;
                        symbols.Add(new Barline()
                        {
                            AlternateRepeatGroup = alternativeRepeatNumber
                        });
                    }
                    break;

                case LilypondTokenKind.Alternative:
                    inAlternative = true;
                    inRepeat      = false;
                    currentToken  = currentToken.NextToken;    // Skip the first bracket open.
                    break;

                case LilypondTokenKind.Note:
                    // Tied
                    // TODO: A tie, like a dot and cross or mole are decorations on notes. Is the DECORATOR pattern of use here?
                    NoteTieType tie = NoteTieType.None;
                    if (currentToken.Value.StartsWith("~"))
                    {
                        tie = NoteTieType.Stop;
                        var lastNote = symbols.Last(s => s is Note) as Note;
                        if (lastNote != null)
                        {
                            lastNote.TieType = NoteTieType.Start;
                        }
                        currentToken.Value = currentToken.Value.Substring(1);
                    }
                    // Length
                    int noteLength = Int32.Parse(Regex.Match(currentToken.Value, @"\d+").Value);
                    // Crosses and Moles
                    int alter = 0;
                    alter += Regex.Matches(currentToken.Value, "is").Count;
                    alter -= Regex.Matches(currentToken.Value, "es|as").Count;
                    // Octaves
                    int distanceWithPreviousNote = notesorder.IndexOf(currentToken.Value[0]) - notesorder.IndexOf(previousNote);
                    if (distanceWithPreviousNote > 3)     // Shorter path possible the other way around
                    {
                        distanceWithPreviousNote -= 7;    // The number of notes in an octave
                    }
                    else if (distanceWithPreviousNote < -3)
                    {
                        distanceWithPreviousNote += 7;     // The number of notes in an octave
                    }

                    if (distanceWithPreviousNote + notesorder.IndexOf(previousNote) >= 7)
                    {
                        previousOctave++;
                    }
                    else if (distanceWithPreviousNote + notesorder.IndexOf(previousNote) < 0)
                    {
                        previousOctave--;
                    }

                    // Force up or down.
                    previousOctave += currentToken.Value.Count(c => c == '\'');
                    previousOctave -= currentToken.Value.Count(c => c == ',');

                    previousNote = currentToken.Value[0];

                    var note = new Note(currentToken.Value[0].ToString().ToUpper(), alter, previousOctave, (MusicalSymbolDuration)noteLength, NoteStemDirection.Up, tie, new List <NoteBeamType>()
                    {
                        NoteBeamType.Single
                    });
                    note.NumberOfDots += currentToken.Value.Count(c => c.Equals('.'));

                    symbols.Add(note);
                    break;

                case LilypondTokenKind.Rest:
                    var restLength = Int32.Parse(currentToken.Value[1].ToString());
                    symbols.Add(new Rest((MusicalSymbolDuration)restLength));
                    break;

                case LilypondTokenKind.Bar:
                    symbols.Add(new Barline()
                    {
                        AlternateRepeatGroup = alternativeRepeatNumber
                    });
                    break;

                case LilypondTokenKind.Clef:
                    currentToken = currentToken.NextToken;
                    if (currentToken.Value == "treble")
                    {
                        currentClef = new Clef(ClefType.GClef, 2);
                    }
                    else if (currentToken.Value == "bass")
                    {
                        currentClef = new Clef(ClefType.FClef, 4);
                    }
                    else
                    {
                        throw new NotSupportedException($"Clef {currentToken.Value} is not supported.");
                    }

                    symbols.Add(currentClef);
                    break;

                case LilypondTokenKind.Time:
                    currentToken = currentToken.NextToken;
                    var times = currentToken.Value.Split('/');
                    symbols.Add(new TimeSignature(TimeSignatureType.Numbers, UInt32.Parse(times[0]), UInt32.Parse(times[1])));
                    break;

                case LilypondTokenKind.Tempo:
                    // Tempo not supported
                    break;

                default:
                    break;
                }
                currentToken = currentToken.NextToken;
            }

            return(symbols);
        }
コード例 #11
0
        public void Solve(LilypondContext context, LilypondToken token)
        {
            var restLength = Int32.Parse(token.Value[1].ToString());

            context.Symbols.Add(new Rest((MusicalSymbolDuration)restLength));
        }
コード例 #12
0
 public void Solve(LilypondContext context, LilypondToken token)
 {
     context.Symbols.Add(new Barline());
 }
コード例 #13
0
 public void Solve(LilypondContext context, LilypondToken token)
 {
     // Tempo not supported
 }
コード例 #14
0
ファイル: FileHandler.cs プロジェクト: glenndewildt/DPA
        private static IEnumerable <MusicalSymbol> GetStaffsFromTokens(LinkedList <LilypondToken> tokens, out string message)
        {
            List <MusicalSymbol> symbols = new List <MusicalSymbol>();

            message = "";

            try
            {
                Clef currentClef    = null;
                int  previousOctave = 4;
                char previousNote   = 'c';

                LilypondToken currentToken = tokens.First();
                while (currentToken != null)
                {
                    switch (currentToken.TokenKind)
                    {
                    case LilypondTokenKind.Unknown:
                        break;

                    case LilypondTokenKind.Note:
                        // Length
                        int noteLength = Int32.Parse(Regex.Match(currentToken.Value, @"\d+").Value);
                        // Crosses and Moles
                        int alter = 0;
                        alter += Regex.Matches(currentToken.Value, "is").Count;
                        alter -= Regex.Matches(currentToken.Value, "es|as").Count;
                        // Octaves
                        int distanceWithPreviousNote = notesorder.IndexOf(currentToken.Value[0]) - notesorder.IndexOf(previousNote);
                        if (distanceWithPreviousNote > 3)     // Shorter path possible the other way around
                        {
                            distanceWithPreviousNote -= 7;    // The number of notes in an octave
                        }
                        else if (distanceWithPreviousNote < -3)
                        {
                            distanceWithPreviousNote += 7;     // The number of notes in an octave
                        }

                        if (distanceWithPreviousNote + notesorder.IndexOf(previousNote) >= 7)
                        {
                            previousOctave++;
                        }
                        else if (distanceWithPreviousNote + notesorder.IndexOf(previousNote) < 0)
                        {
                            previousOctave--;
                        }

                        // Force up or down.
                        previousOctave += currentToken.Value.Count(c => c == '\'');
                        previousOctave -= currentToken.Value.Count(c => c == ',');

                        previousNote = currentToken.Value[0];

                        var note = new PSAMControlLibrary.Note(currentToken.Value[0].ToString().ToUpper(), alter, previousOctave, (MusicalSymbolDuration)noteLength, NoteStemDirection.Up, NoteTieType.None, new List <NoteBeamType>()
                        {
                            NoteBeamType.Single
                        });
                        note.NumberOfDots += currentToken.Value.Count(c => c.Equals('.'));

                        symbols.Add(note);
                        break;

                    case LilypondTokenKind.Rest:
                        var restLength = Int32.Parse(currentToken.Value[1].ToString());
                        symbols.Add(new Rest((MusicalSymbolDuration)restLength));
                        break;

                    case LilypondTokenKind.Bar:
                        symbols.Add(new Barline());
                        break;

                    case LilypondTokenKind.Clef:
                        currentToken = currentToken.NextToken;
                        if (currentToken.Value == "treble")
                        {
                            currentClef = new Clef(ClefType.GClef, 2);
                        }
                        else if (currentToken.Value == "bass")
                        {
                            currentClef = new Clef(ClefType.FClef, 4);
                        }
                        else
                        {
                            throw new NotSupportedException($"Clef {currentToken.Value} is not supported.");
                        }

                        symbols.Add(currentClef);
                        break;

                    case LilypondTokenKind.Time:
                        currentToken = currentToken.NextToken;
                        var times = currentToken.Value.Split('/');
                        symbols.Add(new TimeSignature(TimeSignatureType.Numbers, UInt32.Parse(times[0]), UInt32.Parse(times[1])));
                        break;

                    case LilypondTokenKind.Tempo:
                        // Tempo not supported
                        break;

                    default:
                        break;
                    }
                    currentToken = currentToken.NextToken;
                }
            }
            catch (Exception ex)
            {
                message = ex.Message;
            }

            return(symbols);
        }