Example #1
0
        void ParseLength(out Length length, out int dots)
        {
            float noteDuration = ParserUtil.lengthDurations[unitNoteLength];

            noteDuration *= ReadDurationModifier();

            if (!ParserUtil.ParseDuration(noteDuration, out length, out dots))
            {
                throw new ParseException($"Invalid Note duration at {lineNum}, {index}");
            }
        }
Example #2
0
        float ReadDurationModifier()
        {
            // length modifier will be either '/*' or '\d*/N'
            ReadUntil((char c) => { return(!char.IsDigit(c) && c != '/'); }, out string lengthMod);

            try
            {
                return(ParserUtil.ParseDurationModifierString(lengthMod));
            }
            catch (FormatException)
            {
                throw new ParseException($"Unable to parse length modifier at {lineNum}, {index}");
            }
        }
Example #3
0
        void UpdateBrokenRhythm()
        {
            if (brokenRhythm == BrokenRhythm.None)
            {
                return;
            }

            if (voice.items.Count < 2)
            {
                throw new ParseException($"Unable to apply broken rhythm to item near {lineNum}, {index}");
            }

            var itemA = voice.items[voice.items.Count - 2] as Duration;
            var itemB = voice.items[voice.items.Count - 1] as Duration;

            if (itemA == null || itemB == null)
            {
                throw new ParseException($"Unable to apply broken rhythm to item near {lineNum}, {index}");
            }

            Duration halfItem, dotItem;

            if (brokenRhythm == BrokenRhythm.DotHalf)
            {
                dotItem  = itemA;
                halfItem = itemB;
            }
            else
            {
                dotItem  = itemB;
                halfItem = itemA;
            }

            dotItem.dotCount = brokenRhythmCount;

            var duration = ParserUtil.lengthDurations[halfItem.length] * (1.0f / (1 << brokenRhythmCount));

            ParserUtil.ParseDuration(duration, out Length l, out int dots);
            halfItem.length   = l;
            halfItem.dotCount = dots;

            brokenRhythm = BrokenRhythm.None;
        }
Example #4
0
        void ParseChord()
        {
            EnsureVoice();

            CheckForLineBreak();

            index += 1;
            var   notes = new List <Note>();
            float noteDurationModifier = 1.0f;

            do
            {
                if (SkipWhiteSpace())
                {
                    throw new ParseException($"Unterminated chord at {lineNum}, {index}");
                }

                if (!Elements.IsStartOfNoteStream(currentLine[index]))
                {
                    throw new ParseException($"Invalid character in chord at {lineNum}, {index}");
                }

                notes.Add(ReadBaseNote());

                //only the duration modifier for the first chord will have impact on its overall duration
                float durationModifier = ReadDurationModifier();
                if (notes.Count == 1)
                {
                    noteDurationModifier = durationModifier;
                }

                if (index == currentLine.Length)
                {
                    throw new ParseException($"Unterminated chord at {lineNum}, {index}");
                }
            } while (currentLine[index] != ']');

            index += 1;

            if (notes.Count == 0)
            {
                throw new ParseException($"Encountered empty chord at {lineNum}, {index}");
            }

            var   chord = Chord.FromNotes(notes);
            float chordDurationModifier = ReadDurationModifier();
            // spec states that length modifiers inside the chord are multiplied by outside
            float noteDuration = ParserUtil.lengthDurations[unitNoteLength] * (noteDurationModifier * chordDurationModifier);

            if (!ParserUtil.ParseDuration(noteDuration, out Length chordLength, out int dotCount))
            {
                throw new ParseException($"Invalid Note duration at {lineNum}, {index}");
            }

            chord.length   = chordLength;
            chord.dotCount = dotCount;

            UpdateBeam(chord);
            voice.items.Add(chord);
            SetDecorationsForItem(chord);
        }