예제 #1
0
        public Song Parse()
        {
            var song = new Song();

            int?tempo = _score.Parts.First().Measures.First().Directions.Where(x => x.Placement == DirectionPlacement.Above).First().Tempo;

            if (tempo == null)
            {
                song.Tempo = 100;
            }
            else
            {
                song.Tempo = (int)tempo;
            }

            double currentNoteTime  = 0;
            double currentDevisions = 4;

            //foreach (Part part in _score.Parts)
            Part part = MusicXmlHelpers.SelectPianoPart(_score);

            foreach (Measure measure in part.Measures)
            {
                MeasureAttributes attributes = measure.Attributes;
                if (attributes != null)
                {
                    if (attributes.Divisions != -1)
                    {
                        currentDevisions = attributes.Divisions;
                    }
                }

                double lastXmlNoteDuration = 0;

                foreach (Note note in measure.Notes)
                {
                    double noteDuration = note.Duration / currentDevisions;
                    //If the current note is part of a chord, we need to revert to the previous NoteTime
                    if (note.IsChord)
                    {
                        currentNoteTime -= lastXmlNoteDuration;
                    }

                    //After current note drawn, handle keeping track of noteTime in the piece
                    switch (note.NoteType)
                    {
                    case Note.NoteTypes.Note:
                        if (note.TieType == TieType.Stop)
                        {
                            ExtendSongNote(currentNoteTime, song, note, noteDuration);
                        }
                        else
                        {
                            AddSongNoteToSong(currentNoteTime, song, note, noteDuration);
                        }
                        currentNoteTime += noteDuration;
                        break;

                    case Note.NoteTypes.Backup:
                        currentNoteTime -= noteDuration;
                        break;

                    case Note.NoteTypes.Forward:
                        currentNoteTime += noteDuration;
                        break;

                    default:
                        currentNoteTime += noteDuration;
                        break;
                    }
                    lastXmlNoteDuration = noteDuration;
                }
            }

            song = BuildKeyReleases(song);

            return(song);
        }
예제 #2
0
        public void Render()
        {
            _renderHelper = new RenderHelper(_scorePanel);

            double currentNoteTime  = 0;
            int    currentDivisions = 0;

            var staffs = new Staffs(_renderHelper);

            staffs.Add(new Staff(_renderHelper, ScoreLayoutDetails.LineSpacing_Y, ScoreLayoutDetails.Staff1_FristLineY));

            if (_score == null)
            {
                throw new Exception("Score is empty, doh..");
            }

            Part part = MusicXmlHelpers.SelectPianoPart(_score);

            double numberOfStaves = MusicXmlHelpers.GetNumberOfStaves(part);

            //Only add a second stave if nec.
            if (numberOfStaves == 2)
            {
                staffs.Add(new Staff(_renderHelper, ScoreLayoutDetails.LineSpacing_Y, ScoreLayoutDetails.Staff2_FristLineY));
            }

            staffs.AddBarLine(currentNoteTime);

            //foreach (Part part in _score.Parts)
            foreach (Measure measure in part.Measures)
            {
                MeasureAttributes attributes = measure.Attributes;
                if (attributes != null)
                {
                    if (attributes.Divisions != -1)
                    {
                        currentDivisions = attributes.Divisions;
                    }

                    UpdateMeasureAttributes(attributes, staffs, currentNoteTime);
                }

                double lastNoteDuration = 0;

                foreach (Note note in measure.Notes)
                {
                    //If the current note is part of a chord, we need to revert to the previous NoteTime
                    if (note.IsChord)
                    {
                        currentNoteTime -= 1.0 * lastNoteDuration / currentDivisions;
                    }

                    Staff staff = GetStaffFromNote(staffs, note);
                    if (staff != null && note.IsDrawableEntity)
                    {
                        staff.AddNote(note, currentDivisions, currentNoteTime);
                    }

                    //After current note drawn, handle keeping track of noteTime in the piece
                    switch (note.NoteType)
                    {
                    case Note.NoteTypes.Backup: currentNoteTime -= 1.0 * note.Duration / currentDivisions;
                        break;

                    case Note.NoteTypes.Forward: currentNoteTime += 1.0 * note.Duration / currentDivisions;
                        break;

                    default: currentNoteTime += 1.0 * note.Duration / currentDivisions;
                        break;
                    }

                    lastNoteDuration = note.Duration;
                }

                staffs.AddBarLine(currentNoteTime);
            }

            double finalX = _renderHelper.RenderItems(ScoreLayoutDetails.DefaultMargin_X);

            foreach (var staff in staffs)
            {
                staff.DrawStaffLines(ScoreLayoutDetails.DefaultMargin_X, finalX);
            }
        }