/// <summary> /// Checks whether the current beat is timewise before the given beat. /// </summary> /// <param name="beat"></param> /// <returns></returns> internal bool IsBefore(Beat beat) { return(Voice.Bar.Index < beat.Voice.Bar.Index || beat.Voice.Bar.Index == Voice.Bar.Index && Index < beat.Index); }
/// <summary> /// Checks whether the current beat is timewise after the given beat. /// </summary> /// <param name="beat"></param> /// <returns></returns> internal bool IsAfter(Beat beat) { return(Voice.Bar.Index > beat.Voice.Bar.Index || beat.Voice.Bar.Index == Voice.Bar.Index && Index > beat.Index); }
internal void Finish() { var needCopyBeatForBend = false; MinNote = null; MaxNote = null; MinStringNote = null; MaxStringNote = null; var visibleNotes = 0; var isEffectSlurBeat = false; for (int i = 0, j = Notes.Count; i < j; i++) { var note = Notes[i]; note.Finish(); if (note.IsLetRing) { IsLetRing = true; } if (note.IsPalmMute) { IsPalmMute = true; } if (note.IsVisible) { visibleNotes++; if (MinNote == null || note.RealValue < MinNote.RealValue) { MinNote = note; } if (MaxNote == null || note.RealValue > MaxNote.RealValue) { MaxNote = note; } if (MinStringNote == null || note.String < MinStringNote.String) { MinStringNote = note; } if (MaxStringNote == null || note.String > MaxStringNote.String) { MaxStringNote = note; } if (note.HasEffectSlur) { isEffectSlurBeat = true; } } } if (isEffectSlurBeat) { if (EffectSlurOrigin != null) { EffectSlurOrigin.EffectSlurDestination = NextBeat; EffectSlurOrigin.EffectSlurDestination.EffectSlurOrigin = EffectSlurOrigin; EffectSlurOrigin = null; } else { IsEffectSlurOrigin = true; EffectSlurDestination = NextBeat; EffectSlurDestination.EffectSlurOrigin = this; } } if (Notes.Count > 0 && visibleNotes == 0) { IsEmpty = true; } // we need to clean al letring/palmmute flags for rests // in case the effect is not continued on this beat if (!IsRest && (!IsLetRing || !IsPalmMute)) { var currentBeat = PreviousBeat; while (currentBeat != null && currentBeat.IsRest) { if (!IsLetRing) { currentBeat.IsLetRing = false; } if (!IsPalmMute) { currentBeat.IsPalmMute = false; } currentBeat = currentBeat.PreviousBeat; } } // try to detect what kind of bend was used and cleans unneeded points if required // Guitar Pro 6 and above (gpif.xml) uses exactly 4 points to define all whammys if (WhammyBarPoints.Count > 0 && WhammyBarType == WhammyType.Custom) { var isContinuedWhammy = IsContinuedWhammy = PreviousBeat != null && PreviousBeat.HasWhammyBar; if (WhammyBarPoints.Count == 4) { var origin = WhammyBarPoints[0]; var middle1 = WhammyBarPoints[1]; var middle2 = WhammyBarPoints[2]; var destination = WhammyBarPoints[3]; // the middle points are used for holds, anything else is a new feature we do not support yet if (middle1.Value == middle2.Value) { // constant decrease or increase if (origin.Value < middle1.Value && middle1.Value < destination.Value || origin.Value > middle1.Value && middle1.Value > destination.Value) { if (origin.Value != 0 && !isContinuedWhammy) { WhammyBarType = WhammyType.PrediveDive; } else { WhammyBarType = WhammyType.Dive; } WhammyBarPoints.RemoveAt(2); WhammyBarPoints.RemoveAt(1); } // down-up or up-down else if (origin.Value > middle1.Value && middle1.Value < destination.Value || origin.Value < middle1.Value && middle1.Value > destination.Value) { WhammyBarType = WhammyType.Dip; } else if (origin.Value == middle1.Value && middle1.Value == destination.Value) { if (origin.Value != 0 && !isContinuedWhammy) { WhammyBarType = WhammyType.Predive; } else { WhammyBarType = WhammyType.Hold; } WhammyBarPoints.RemoveAt(2); WhammyBarPoints.RemoveAt(1); } else { Logger.Warning("Model", "Unsupported whammy type detected, fallback to custom"); } } else { Logger.Warning("Model", "Unsupported whammy type detected, fallback to custom"); } } } UpdateDurations(); if (needCopyBeatForBend) { // if this beat is a simple bend convert it to a grace beat // and generate a placeholder beat with tied notes var cloneBeat = Clone(); cloneBeat.Id = _globalBeatId++; for (int i = 0, j = cloneBeat.Notes.Count; i < j; i++) { var cloneNote = cloneBeat.Notes[i]; // remove bend on cloned note cloneNote.BendType = BendType.None; cloneNote.MaxBendPoint = null; cloneNote.BendPoints = new FastList <BendPoint>(); cloneNote.BendStyle = BendStyle.Default; cloneNote.Id = Note.GlobalNoteId++; // if the note has a bend which is continued on the next note // we need to convert this note into a hold bend var note = Notes[i]; if (note.HasBend && note.IsTieOrigin) { var tieDestination = Note.NextNoteOnSameLine(note); if (tieDestination != null && tieDestination.HasBend) { cloneNote.BendType = BendType.Hold; var lastPoint = note.BendPoints[note.BendPoints.Count - 1]; cloneNote.AddBendPoint(new BendPoint(0, lastPoint.Value)); cloneNote.AddBendPoint(new BendPoint(BendPoint.MaxPosition, lastPoint.Value)); } } // mark as tied note cloneNote.IsTieDestination = true; } GraceType = GraceType.BendGrace; UpdateDurations(); Voice.InsertBeat(this, cloneBeat); } Fermata = Voice.Bar.MasterBar.GetFermata(this); }