Example #1
0
        private Beat GetOrCreateBeat(IXmlNode element, Bar[] bars, bool chord)
        {
            int voiceIndex = 0;
            var voiceNodes = element.GetElementsByTagName("voice");

            if (voiceNodes.Length > 0)
            {
                voiceIndex = Std.ParseInt(Std.GetNodeValue(voiceNodes[0])) - 1;
            }

            var previousBeatWasPulled = _previousBeatWasPulled;

            _previousBeatWasPulled = false;
            var staffElement = element.GetElementsByTagName("staff");
            int staff        = 1;

            if (staffElement.Length > 0)
            {
                staff = Std.ParseInt(Std.GetNodeValue(staffElement[0]));

                // in case we have a beam with a staff-jump we pull the note to the previous staff
                if ((_isBeamContinue || previousBeatWasPulled) && _previousBeat.Voice.Bar.Staff.Index != staff - 1)
                {
                    staff = _previousBeat.Voice.Bar.Staff.Index + 1;
                    _previousBeatWasPulled = true;
                }

                var staffId = bars[0].Staff.Track.Index + "-" + staff;
                if (!_voiceOfStaff.ContainsKey(staffId))
                {
                    _voiceOfStaff[staffId] = voiceIndex;
                }
                voiceIndex -= _voiceOfStaff[staffId];
            }
            var bar = bars[staff - 1];

            Beat beat;
            var  voice = GetOrCreateVoice(bar, voiceIndex);

            if (chord || (voice.Beats.Count == 1 && voice.IsEmpty))
            {
                beat = voice.Beats[voice.Beats.Count - 1];
            }
            else
            {
                beat = new Beat();
                voice.AddBeat(beat);
            }

            _isBeamContinue = false;
            _previousBeat   = beat;

            return(beat);
        }
Example #2
0
        private void ParseForward(IXmlNode element, Bar[] bars)
        {
            var beat = GetOrCreateBeat(element, bars, false);
            var durationInDivisions = Std.ParseInt(Std.GetNodeValue(element.GetElementsByTagName("duration")[0]));

            var duration = (durationInDivisions * (int)Duration.Quarter) / (float)_divisionsPerQuarterNote;

            var durations = new[]
            {
                (int)Duration.SixtyFourth,
                (int)Duration.ThirtySecond,
                (int)Duration.Sixteenth,
                (int)Duration.Eighth,
                (int)Duration.Quarter,
                (int)Duration.Half,
                (int)Duration.Whole
            };

            foreach (var d in durations)
            {
                if (duration >= d)
                {
                    beat.Duration = (Duration)d;
                    duration     -= d;
                    break;
                }
            }

            if (duration > 0)
            {
                // TODO: Handle remaining duration
                // (additional beats, dotted durations,...)
            }

            beat.IsEmpty = false;
        }
Example #3
0
        private bool ParseNoteBeat(IXmlNode element, Track track, Bar bar, bool chord, bool isFirstBeat)
        {
            int voiceIndex = 0;
            var voiceNodes = element.GetElementsByTagName("voice");
            if (voiceNodes.Length > 0)
            {
                voiceIndex = Std.ParseInt(Std.GetNodeValue(voiceNodes[0])) - 1;
            }

            Beat beat;
            var voice = GetOrCreateVoice(bar, voiceIndex);
            if (chord || (isFirstBeat && voice.Beats.Count == 1))
            {
                beat = voice.Beats[voice.Beats.Count - 1];
            }
            else
            {
                beat = new Beat();
                voice.AddBeat(beat);
            }

            var note = new Note();
            beat.AddNote(note);
            beat.IsEmpty = false;

            element.IterateChildren(c =>
            {
                if (c.NodeType == XmlNodeType.Element)
                {
                    switch (c.LocalName)
                    {
                        case "grace":
                            //var slash = e.GetAttribute("slash");
                            //var makeTime = Std.ParseInt(e.GetAttribute("make-time"));
                            //var stealTimePrevious = Std.ParseInt(e.GetAttribute("steal-time-previous"));
                            //var stealTimeFollowing = Std.ParseInt(e.GetAttribute("steal-time-following"));
                            beat.GraceType = GraceType.BeforeBeat;
                            beat.Duration = Duration.ThirtySecond;
                            break;
                        case "duration":
                            beat.Duration = (Duration)Std.ParseInt(Std.GetNodeValue(c));
                            break;
                        case "tie":
                            ParseTied(c, note);
                            break;
                        case "cue":
                            // not supported
                            break;
                        case "instrument":
                            // not supported
                            break;
                        case "type":
                            switch (Std.GetNodeValue(c))
                            {
                                case "256th":
                                    beat.Duration = Duration.TwoHundredFiftySixth;
                                    break;
                                case "128th":
                                    beat.Duration = Duration.OneHundredTwentyEighth;
                                    break;
                                case "breve":
                                    beat.Duration = Duration.DoubleWhole;
                                    break;
                                case "long":
                                    beat.Duration = Duration.QuadrupleWhole;
                                    break;
                                case "64th":
                                    beat.Duration = Duration.SixtyFourth;
                                    break;
                                case "32nd":
                                    beat.Duration = Duration.ThirtySecond;
                                    break;
                                case "16th":
                                    beat.Duration = Duration.Sixteenth;
                                    break;
                                case "eighth":
                                    beat.Duration = Duration.Eighth;
                                    break;
                                case "quarter":
                                    beat.Duration = Duration.Quarter;
                                    break;
                                case "half":
                                    beat.Duration = Duration.Half;
                                    break;
                                case "whole":
                                    beat.Duration = Duration.Whole;
                                    break;
                            }
                            break;
                        case "dot":
                            note.IsStaccato = true;
                            break;
                        case "accidental":
                            ParseAccidental(c, note);
                            break;
                        case "time-modification":
                            ParseTimeModification(c, beat);
                            break;
                        case "stem":
                            // not supported
                            break;
                        case "notehead":
                            if (c.GetAttribute("parentheses") == "yes")
                            {
                                note.IsGhost = true;
                            }
                            break;
                        case "beam":
                            // not supported
                            break;
                        case "notations":
                            ParseNotations(c, beat, note);
                            break;
                        case "lyric":
                            // not supported
                            break;
                        // "full-note"
                        case "chord":
                            chord = true;
                            break;
                        case "pitch":
                            ParsePitch(c, track, beat, note);
                            break;
                        case "unpitched":
                            // TODO: not yet fully supported
                            note.String = 0;
                            note.Fret = 0;
                            break;
                        case "rest":
                            beat.IsEmpty = false;
                            break;
                    }
                }
            });

            return chord;
        }
Example #4
0
        private bool ParseNoteBeat(IXmlNode element, Track track, Bar bar, bool chord, bool isFirstBeat)
        {
            int voiceIndex = 0;
            var voiceNodes = element.GetElementsByTagName("voice");

            if (voiceNodes.Count > 0)
            {
                voiceIndex = Std.ParseInt(Std.GetNodeValue(voiceNodes[0])) - 1;
            }

            Beat beat;
            var  voice = GetOrCreateVoice(bar, voiceIndex);

            if (chord || (isFirstBeat && voice.Beats.Count == 1))
            {
                beat = voice.Beats[voice.Beats.Count - 1];
            }
            else
            {
                beat = new Beat();
                voice.AddBeat(beat);
            }

            var note = new Note();

            beat.AddNote(note);
            beat.IsEmpty = false;

            element.IterateChildren(c =>
            {
                if (c.NodeType == XmlNodeType.Element)
                {
                    switch (c.LocalName)
                    {
                    case "grace":
                        //var slash = e.GetAttribute("slash");
                        //var makeTime = Std.ParseInt(e.GetAttribute("make-time"));
                        //var stealTimePrevious = Std.ParseInt(e.GetAttribute("steal-time-previous"));
                        //var stealTimeFollowing = Std.ParseInt(e.GetAttribute("steal-time-following"));
                        beat.GraceType = GraceType.BeforeBeat;
                        beat.Duration  = Duration.ThirtySecond;
                        break;

                    case "duration":
                        beat.Duration = (Duration)Std.ParseInt(Std.GetNodeValue(c));
                        break;

                    case "tie":
                        ParseTied(c, note);
                        break;

                    case "cue":
                        // not supported
                        break;

                    case "instrument":
                        // not supported
                        break;

                    case "type":
                        switch (Std.GetNodeValue(c))
                        {
                        //case "256th":
                        //    break;
                        //case "128th":
                        //    break;
                        //case "breve":
                        //    break;
                        //case "long":
                        //    break;
                        case "64th":
                            beat.Duration = Duration.SixtyFourth;
                            break;

                        case "32nd":
                            beat.Duration = Duration.ThirtySecond;
                            break;

                        case "16th":
                            beat.Duration = Duration.Sixteenth;
                            break;

                        case "eighth":
                            beat.Duration = Duration.Eighth;
                            break;

                        case "quarter":
                            beat.Duration = Duration.Quarter;
                            break;

                        case "half":
                            beat.Duration = Duration.Half;
                            break;

                        case "whole":
                            beat.Duration = Duration.Whole;
                            break;
                        }
                        break;

                    case "dot":
                        note.IsStaccato = true;
                        break;

                    case "accidental":
                        ParseAccidental(c, note);
                        break;

                    case "time-modification":
                        ParseTimeModification(c, beat);
                        break;

                    case "stem":
                        // not supported
                        break;

                    case "notehead":
                        if (c.GetAttribute("parentheses") == "yes")
                        {
                            note.IsGhost = true;
                        }
                        break;

                    case "beam":
                        // not supported
                        break;

                    case "notations":
                        ParseNotations(c, beat, note);
                        break;

                    case "lyric":
                        // not supported
                        break;

                    // "full-note"
                    case "chord":
                        chord = true;
                        break;

                    case "pitch":
                        ParsePitch(c, track, beat, note);
                        break;

                    case "unpitched":
                        // TODO: not yet fully supported
                        note.String = 0;
                        note.Fret   = 0;
                        break;

                    case "rest":
                        beat.IsEmpty = false;
                        break;
                    }
                }
            });

            return(chord);
        }
Example #5
0
        private void ParseNoteBeat(IXmlNode element, Bar[] bars)
        {
            var chord = element.GetElementsByTagName("chord").Length > 0;
            var beat  = GetOrCreateBeat(element, bars, chord);

            beat.ChordId  = _currentChord;
            _currentChord = null;

            var note = new Note();

            beat.AddNote(note);
            beat.IsEmpty = false;

            beat.Dots = 0;
            element.IterateChildren(c =>
            {
                if (c.NodeType == XmlNodeType.Element)
                {
                    switch (c.LocalName)
                    {
                    case "grace":
                        //var slash = e.GetAttribute("slash");
                        //var makeTime = Std.ParseInt(e.GetAttribute("make-time"));
                        //var stealTimePrevious = Std.ParseInt(e.GetAttribute("steal-time-previous"));
                        //var stealTimeFollowing = Std.ParseInt(e.GetAttribute("steal-time-following"));
                        beat.GraceType = GraceType.BeforeBeat;
                        beat.Duration  = Duration.ThirtySecond;
                        break;

                    case "duration":
                        if (beat.IsRest)
                        {
                            // unit: divisions per quarter note
                            var duration = Std.ParseInt(Std.GetNodeValue(c));
                            switch (duration)
                            {
                            case 1:
                                beat.Duration = Duration.Whole;
                                break;

                            case 2:
                                beat.Duration = Duration.Half;
                                break;

                            case 4:
                                beat.Duration = Duration.Quarter;
                                break;

                            case 8:
                                beat.Duration = Duration.Eighth;
                                break;

                            case 16:
                                beat.Duration = Duration.Sixteenth;
                                break;

                            case 32:
                                beat.Duration = Duration.ThirtySecond;
                                break;

                            case 64:
                                beat.Duration = Duration.SixtyFourth;
                                break;

                            default:
                                beat.Duration = Duration.Quarter;
                                break;
                            }
                        }
                        break;

                    case "tie":
                        ParseTied(c, note);
                        break;

                    case "cue":
                        // not supported
                        break;

                    case "instrument":
                        // not supported
                        break;

                    case "type":
                        switch (Std.GetNodeValue(c))
                        {
                        case "256th":
                        case "128th":
                        case "64th":
                            beat.Duration = Duration.SixtyFourth;
                            break;

                        case "32nd":
                            beat.Duration = Duration.ThirtySecond;
                            break;

                        case "16th":
                            beat.Duration = Duration.Sixteenth;
                            break;

                        case "eighth":
                            beat.Duration = Duration.Eighth;
                            break;

                        case "quarter":
                            beat.Duration = Duration.Quarter;
                            break;

                        case "half":
                            beat.Duration = Duration.Half;
                            break;

                        case "long":
                        case "breve":
                        case "whole":
                            beat.Duration = Duration.Whole;
                            break;
                        }
                        if (beat.GraceType != GraceType.None && beat.Duration < Duration.Sixteenth)
                        {
                            beat.Duration = Duration.Eighth;
                        }
                        break;

                    case "dot":
                        beat.Dots++;
                        break;

                    case "accidental":
                        ParseAccidental(c, note);
                        break;

                    case "time-modification":
                        ParseTimeModification(c, beat);
                        break;

                    case "stem":
                        // not supported
                        break;

                    case "notehead":
                        if (c.GetAttribute("parentheses") == "yes")
                        {
                            note.IsGhost = true;
                        }
                        break;

                    case "beam":
                        var beamMode = Std.GetNodeValue(c);
                        if (beamMode == "continue")
                        {
                            _isBeamContinue = true;
                        }
                        break;

                    case "notations":
                        ParseNotations(c, beat, note);
                        break;

                    case "lyric":
                        ParseLyric(c, beat);
                        break;

                    // "full-note"
                    case "pitch":
                        ParsePitch(c, note);
                        break;

                    case "unpitched":
                        ParseUnpitched(c, note);
                        break;

                    case "rest":
                        beat.IsEmpty = false;
                        beat.Notes.Clear();
                        break;
                    }
                }
            });

            // check if new note is duplicate on string
            if (note.IsStringed)
            {
                for (int i = 0; i < beat.Notes.Count; i++)
                {
                    if (beat.Notes[i].String == note.String && beat.Notes[i] != note)
                    {
                        beat.RemoveNote(note);
                        break;
                    }
                }
            }
        }
Example #6
0
        private void ParseHarmony(IXmlNode element, Track track)
        {
            var root     = element.GetElementsByTagName("root")[0];
            var rootStep = Std.GetNodeValue(root.GetElementsByTagName("root-step")[0]);
            var kind     = Std.GetNodeValue(element.GetElementsByTagName("kind")[0]);

            var chord = new Chord();

            chord.Name = rootStep;
            // TODO: find proper names for the rest
            //switch (kind)
            //{
            //    // triads
            //    case "major":
            //        break;
            //    case "minor":
            //        chord.Name += "m";
            //        break;
            //    // Sevenths
            //    case "augmented":
            //        break;
            //    case "diminished":
            //        break;
            //    case "dominant":
            //        break;
            //    case "major-seventh":
            //        chord.Name += "7M";
            //        break;
            //    case "minor-seventh":
            //        chord.Name += "m7";
            //        break;
            //    case "diminished-seventh":
            //        break;
            //    case "augmented-seventh":
            //        break;
            //    case "half-diminished":
            //        break;
            //    case "major-minor":
            //        break;
            //    // Sixths
            //    case "major-sixth":
            //        break;
            //    case "minor-sixth":
            //        break;
            //    // Ninths
            //    case "dominant-ninth":
            //        break;
            //    case "major-ninth":
            //        break;
            //    case "minor-ninth":
            //        break;
            //    // 11ths
            //    case "dominant-11th":
            //        break;
            //    case "major-11th":
            //        break;
            //    case "minor-11th":
            //        break;
            //    // 13ths
            //    case "dominant-13th":
            //        break;
            //    case "major-13th":
            //        break;
            //    case "minor-13th":
            //        break;
            //    // Suspended
            //    case "suspended-second":
            //        break;
            //    case "suspended-fourth":
            //        break;
            //    // Functional sixths
            //    case "Neapolitan":
            //        break;
            //    case "Italian":
            //        break;
            //    case "French":
            //        break;
            //    case "German":
            //        break;
            //    // Other
            //    case "pedal":
            //        break;
            //    case "power":
            //        break;
            //    case "Tristan":
            //        break;
            //}

            //var degree = element.GetElementsByTagName("degree");
            //if (degree.Length > 0)
            //{
            //    var degreeValue = Std.GetNodeValue(degree[0].GetElementsByTagName("degree-value")[0]);
            //    var degreeAlter = Std.GetNodeValue(degree[0].GetElementsByTagName("degree-alter")[0]);
            //    var degreeType = Std.GetNodeValue(degree[0].GetElementsByTagName("degree-type")[0]);

            //    if (!string.IsNullOrEmpty(degreeType))
            //    {
            //        chord.Name += degreeType;
            //    }

            //    if (!string.IsNullOrEmpty(degreeValue))
            //    {
            //        chord.Name += "#" + degreeValue;
            //    }
            //}


            _currentChord = Std.NewGuid();
            track.Chords[_currentChord] = chord;
        }
Example #7
0
        private bool ParseMeasure(IXmlNode element, Track track, bool isFirstMeasure)
        {
            if (element.GetAttribute("implicit") == "yes" && element.GetElementsByTagName("note").Length == 0)
            {
                return(false);
            }

            var barIndex = 0;

            if (isFirstMeasure)
            {
                _divisionsPerQuarterNote = 0;
                _trackFirstMeasureNumber = Std.ParseInt(element.GetAttribute("number"));
                if (_trackFirstMeasureNumber == int.MinValue)
                {
                    _trackFirstMeasureNumber = 0;
                }
                barIndex = 0;
            }
            else
            {
                barIndex = Std.ParseInt(element.GetAttribute("number"));
                if (barIndex == int.MinValue)
                {
                    return(false);
                }
                barIndex -= _trackFirstMeasureNumber;
            }

            // try to find out the number of staffs required
            if (isFirstMeasure)
            {
                var attributes = element.GetElementsByTagName("attributes");
                if (attributes.Length > 0)
                {
                    var stavesElements = attributes[0].GetElementsByTagName("staves");
                    if (stavesElements.Length > 0)
                    {
                        var staves = Std.ParseInt(Std.GetNodeValue(stavesElements[0]));
                        track.EnsureStaveCount(staves);
                    }
                }
            }


            // create empty bars to the current index
            Bar[]     bars      = new Bar[track.Staves.Count];
            MasterBar masterBar = null;

            for (int b = track.Staves[0].Bars.Count; b <= barIndex; b++)
            {
                for (int s = 0; s < track.Staves.Count; s++)
                {
                    var bar = bars[s] = new Bar();
                    if (track.Staves[s].Bars.Count > 0)
                    {
                        var previousBar = track.Staves[s].Bars[track.Staves[s].Bars.Count - 1];
                        bar.Clef = previousBar.Clef;
                    }
                    masterBar = GetOrCreateMasterBar(barIndex);
                    track.AddBarToStaff(s, bar);

                    for (int v = 0; v < _maxVoices; v++)
                    {
                        var emptyVoice = new Voice();
                        bar.AddVoice(emptyVoice);
                        var emptyBeat = new Beat {
                            IsEmpty = true
                        };
                        emptyVoice.AddBeat(emptyBeat);
                    }
                }
            }

            var attributesParsed = false;

            element.IterateChildren(c =>
            {
                if (c.NodeType == XmlNodeType.Element)
                {
                    switch (c.LocalName)
                    {
                    case "note":
                        ParseNoteBeat(c, bars);
                        break;

                    case "forward":
                        ParseForward(c, bars);
                        break;

                    case "direction":
                        ParseDirection(c, masterBar);
                        break;

                    case "attributes":
                        if (!attributesParsed)
                        {
                            ParseAttributes(c, bars, masterBar);
                            attributesParsed = true;
                        }
                        break;

                    case "harmony":
                        ParseHarmony(c, track);
                        break;

                    case "sound":
                        // TODO
                        break;

                    case "barline":
                        ParseBarline(c, masterBar);
                        break;
                    }
                }
            });

            return(true);
        }