public BeatStroke(BeatStrokeDirections d, int v, float s) { Direction = d; Value = v; StartTime = s; }
public List <Note> RetrieveNotes(GP.Track track, int[] tuning, Track myTrack) { List <Note> notes = new List <Note>(); int index = 0; Note[] lastNotes = new Note[10]; bool[] lastWasTie = new bool[10]; for (int x = 0; x < 10; x++) { lastWasTie[x] = false; } //GraceNotes if on beat - reducing the next note's length bool rememberGrace = false; bool rememberedGrace = false; int graceLength = 0; int subtractSubindex = 0; for (int x = 0; x < 10; x++) { lastNotes[x] = null; } int measureIndex = -1; int notesInMeasure = 0; foreach (Measure m in track.Measures) { notesInMeasure = 0; measureIndex++; bool skipVoice = false; if (m.SimileMark == SimileMarks.Simple) //Repeat last measure { int amountNotes = _notesInMeasures[_notesInMeasures.Count - 1]; //misuse prohibited by guitarpro int endPoint = notes.Count; for (int x = endPoint - amountNotes; x < endPoint; x++) { Note newNote = new Note(notes[x]); Measure oldM = track.Measures[measureIndex - 1]; newNote.Index += FlipDuration(oldM.Header.TimeSignature.Denominator) * oldM.Header.TimeSignature.Numerator; notes.Add(newNote); notesInMeasure++; } skipVoice = true; } if (m.SimileMark == SimileMarks.FirstOfDouble || m.SimileMark == SimileMarks.SecondOfDouble) //Repeat first or second of last two measures { int secondAmount = _notesInMeasures[_notesInMeasures.Count - 1]; //misuse prohibited by guitarpro int firstAmount = _notesInMeasures[_notesInMeasures.Count - 2]; int endPoint = notes.Count - secondAmount; for (int x = endPoint - firstAmount; x < endPoint; x++) { Note newNote = new Note(notes[x]); Measure oldM1 = track.Measures[measureIndex - 2]; Measure oldM2 = track.Measures[measureIndex - 1]; newNote.Index += FlipDuration(oldM1.Header.TimeSignature.Denominator) * oldM1.Header.TimeSignature.Numerator; newNote.Index += FlipDuration(oldM2.Header.TimeSignature.Denominator) * oldM2.Header.TimeSignature.Numerator; notes.Add(newNote); notesInMeasure++; } skipVoice = true; } foreach (Voice v in m.Voices) { if (skipVoice) { break; } int subIndex = 0; foreach (Beat b in v.Beats) { if (b.Text != null && !b.Text.Value.Equals("")) { Annotations.Add(new Annotation(b.Text.Value, index + subIndex)); } if (b.Effect.TremoloBar != null) { AddToTremoloBarList(index + subIndex, FlipDuration(b.Duration), b.Effect.TremoloBar, myTrack); } //Prepare Brush or Arpeggio bool hasBrush = false; int brushInit = 0; int brushIncrease = 0; BeatStrokeDirections brushDirection = BeatStrokeDirections.None; if (b.Effect.Stroke != null) { int notesCnt = b.Notes.Count; brushDirection = b.Effect.Stroke.Direction; if (brushDirection != BeatStrokeDirections.None && notesCnt > 1) { hasBrush = true; Duration temp = new Duration(); temp.Value = b.Effect.Stroke.Value; int brushTotalDuration = FlipDuration(temp); int beatTotalDuration = FlipDuration(b.Duration); brushIncrease = brushTotalDuration / (notesCnt); int startPos = index + subIndex + (int)((brushTotalDuration - brushIncrease) * (b.Effect.Stroke.StartTime - 1)); int endPos = startPos + brushTotalDuration - brushIncrease; if (brushDirection == BeatStrokeDirections.Down) { brushInit = startPos; } else { brushInit = endPos; brushIncrease = -brushIncrease; } } } foreach (GP.Note n in b.Notes) { Note note = new Note(); //Beat values note.IsTremoloBarVibrato = b.Effect.Vibrato; note.Fading = Fadings.None; if (b.Effect.FadeIn) { note.Fading = Fadings.FadeIn; } if (b.Effect.FadeOut) { note.Fading = Fadings.FadeOut; } if (b.Effect.VolumeSwell) { note.Fading = Fadings.VolumeSwell; } note.IsSlapped = b.Effect.SlapEffect == SlapEffects.Slapping; note.IsPopped = b.Effect.SlapEffect == SlapEffects.Popping; note.IsHammer = n.Effect.Hammer; note.IsRhTapped = b.Effect.SlapEffect == SlapEffects.Tapping; note.Index = index + subIndex; note.Duration = FlipDuration(b.Duration); //Note values note.Fret = n.Value; note.Str = n.Str; note.Velocity = n.Velocity; note.IsVibrato = n.Effect.Vibrato; note.IsPalmMuted = n.Effect.PalmMute; note.IsMuted = n.Type == NoteTypes.Dead; if (n.Effect.Harmonic != null) { note.HarmonicFret = n.Effect.Harmonic.Fret; if (n.Effect.Harmonic.Fret == 0) //older format.. { if (n.Effect.Harmonic.Type == 2) { note.HarmonicFret = ((ArtificialHarmonic)n.Effect.Harmonic).Pitch.ActualOvertone; } } switch (n.Effect.Harmonic.Type) { case 1: note.Harmonic = HarmonicTypes.Natural; break; case 2: note.Harmonic = HarmonicTypes.Artificial; break; case 3: note.Harmonic = HarmonicTypes.Pinch; break; case 4: note.Harmonic = HarmonicTypes.Tapped; break; case 5: note.Harmonic = HarmonicTypes.Semi; break; default: note.Harmonic = HarmonicTypes.Natural; break; } } if (n.Effect.Slides != null) { foreach (SlideTypes sl in n.Effect.Slides) { note.SlidesToNext = note.SlidesToNext || sl == SlideTypes.ShiftSlideTo || sl == SlideTypes.LegatoSlideTo; note.SlideInFromAbove = note.SlideInFromAbove || sl == SlideTypes.IntoFromAbove; note.SlideInFromBelow = note.SlideInFromBelow || sl == SlideTypes.IntoFromBelow; note.SlideOutDownwards = note.SlideOutDownwards || sl == SlideTypes.OutDownwards; note.SlideOutUpwards = note.SlideOutUpwards || sl == SlideTypes.OutUpwards; } } if (n.Effect.Bend != null) { note.BendPoints = GetBendPoints(index + subIndex, FlipDuration(b.Duration), n.Effect.Bend); } //Ties bool dontAddNote = false; if (n.Type == NoteTypes.Tie) { dontAddNote = true; //Find if note can simply be added to previous note var last = lastNotes[Math.Max(0, note.Str - 1)]; if (last != null) { note.Fret = last.Fret; //For GP3 & GP4 if (last.Harmonic != note.Harmonic || last.HarmonicFret != note.HarmonicFret ) { dontAddNote = false; } if (dontAddNote) { note.Connect = true; last.Duration += note.Duration; last.AddBendPoints(note.BendPoints); } } } else // not a tie { lastWasTie[Math.Max(0, note.Str - 1)] = false; } //Extra notes to replicate certain effects //Triplet Feel if (!BarMaster[measureIndex].TripletFeel.Equals("None")) { TripletFeels trip = BarMaster[measureIndex].TripletFeel; //Check if at regular 8th or 16th beat position bool is8ThPos = subIndex % 480 == 0; bool is16ThPos = subIndex % 240 == 0; bool isFirst = true; //first of note pair if (is8ThPos) { isFirst = subIndex % 960 == 0; } if (is16ThPos) { isFirst = is8ThPos; } bool is8Th = b.Duration.Value == 8 && !b.Duration.IsDotted && !b.Duration.IsDoubleDotted && b.Duration.Tuplet.Enters == 1 && b.Duration.Tuplet.Times == 1; bool is16Th = b.Duration.Value == 16 && !b.Duration.IsDotted && !b.Duration.IsDoubleDotted && b.Duration.Tuplet.Enters == 1 && b.Duration.Tuplet.Times == 1; if ((trip == TripletFeels.Eigth && is8ThPos && is8Th) || (trip == TripletFeels.Sixteenth && is16ThPos && is16Th)) { if (isFirst) { note.Duration = (int)(note.Duration * (4.0f / 3.0f)); } if (!isFirst) { note.Duration = (int)(note.Duration * (2.0f / 3.0f)); note.ResizeValue *= (2.0f / 3.0f); note.Index += (int)(note.Duration * (1.0f / 3.0f)); } } if ((trip == TripletFeels.Dotted8Th && is8ThPos && is8Th) || (trip == TripletFeels.Dotted16Th && is16ThPos && is16Th)) { if (isFirst) { note.Duration = (int)(note.Duration * 1.5f); } if (!isFirst) { note.Duration = (int)(note.Duration * 0.5f); note.ResizeValue *= (0.5f); note.Index += (int)(note.Duration * 0.5f); } } if ((trip == TripletFeels.Scottish8Th && is8ThPos && is8Th) || (trip == TripletFeels.Scottish16Th && is16ThPos && is16Th)) { if (isFirst) { note.Duration = (int)(note.Duration * 0.5f); } if (!isFirst) { note.Duration = (int)(note.Duration * 1.5f); note.ResizeValue *= (1.5f); note.Index -= (int)(note.Duration * 0.5f); } } } //Tremolo Picking & Trill if (n.Effect.TremoloPicking != null || n.Effect.Trill != null) { int len = note.Duration; if (n.Effect.TremoloPicking != null) { len = FlipDuration(n.Effect.TremoloPicking.Duration); } if (n.Effect.Trill != null) { len = FlipDuration(n.Effect.Trill.Duration); } int origDuration = note.Duration; note.Duration = len; note.ResizeValue *= ((float)len / origDuration); int currentIndex = note.Index + len; lastNotes[Math.Max(0, note.Str - 1)] = note; notes.Add(note); notesInMeasure++; dontAddNote = true; //Because we're doing it here already bool originalFret = false; int secondFret = note.Fret; if (n.Effect.Trill != null) { secondFret = n.Effect.Trill.Fret - tuning[note.Str - 1]; } while (currentIndex + len <= note.Index + origDuration) { Note newOne = new Note(note); newOne.Index = currentIndex; if (!originalFret) { newOne.Fret = secondFret; //For trills } lastNotes[Math.Max(0, note.Str - 1)] = newOne; if (n.Effect.Trill != null) { newOne.IsHammer = true; } notes.Add(newOne); notesInMeasure++; currentIndex += len; originalFret = !originalFret; } } //Grace Note if (rememberGrace && note.Duration > graceLength) { int orig = note.Duration; note.Duration -= graceLength; note.ResizeValue *= ((float)note.Duration / orig); //subIndex -= graceLength; rememberedGrace = true; } if (n.Effect.Grace != null) { bool isOnBeat = n.Effect.Grace.IsOnBeat; if (n.Effect.Grace.Duration != -1) { //GP3,4,5 format Note graceNote = new Note(); graceNote.Index = note.Index; graceNote.Fret = n.Effect.Grace.Fret; graceNote.Str = note.Str; Duration dur = new Duration(); dur.Value = n.Effect.Grace.Duration; graceNote.Duration = FlipDuration(dur); //works at least for GP5 if (isOnBeat) { int orig = note.Duration; note.Duration -= graceNote.Duration; note.Index += graceNote.Duration; note.ResizeValue *= ((float)note.Duration / orig); } else { graceNote.Index -= graceNote.Duration; } notes.Add(graceNote); //TODO: insert at correct position! notesInMeasure++; } else { if (isOnBeat) // shorten next note { rememberGrace = true; graceLength = note.Duration; } else //Change previous note { if (notes.Count > 0) { note.Index -= note.Duration; //Can lead to negative indices. Midi should handle that subtractSubindex = note.Duration; } } } } //Dead Notes if (n.Type == NoteTypes.Dead) { int orig = note.Duration; note.Velocity = (int)(note.Velocity * 0.9f); note.Duration /= 6; note.ResizeValue *= ((float)note.Duration / orig); } //Ghost Notes if (n.Effect.PalmMute) { int orig = note.Duration; note.Velocity = (int)(note.Velocity * 0.7f); note.Duration /= 2; note.ResizeValue *= ((float)note.Duration / orig); } if (n.Effect.GhostNote) { note.Velocity = (int)(note.Velocity * 0.8f); } //Staccato, Accented, Heavy Accented if (n.Effect.Staccato) { int orig = note.Duration; note.Duration /= 2; note.ResizeValue *= ((float)note.Duration / orig); } if (n.Effect.AccentuatedNote) { note.Velocity = (int)(note.Velocity * 1.2f); } if (n.Effect.HeavyAccentuatedNote) { note.Velocity = (int)(note.Velocity * 1.4f); } //Arpeggio / Brush if (hasBrush) { note.Index = brushInit; brushInit += brushIncrease; } if (!dontAddNote) { lastNotes[Math.Max(0, note.Str - 1)] = note; notes.Add(note); notesInMeasure++; } } if (rememberedGrace) { subIndex -= graceLength; rememberGrace = false; rememberedGrace = false; } //After the change in duration for the second beat has been done subIndex -= subtractSubindex; subtractSubindex = 0; subIndex += FlipDuration(b.Duration); //Sort brushed tones if (hasBrush && brushDirection == BeatStrokeDirections.Up) { //Have to reorder them xxx123 -> xxx321 int notesCnt = b.Notes.Count; Note[] temp = new Note[notesCnt]; for (int x = notes.Count - notesCnt; x < notes.Count; x++) { temp[x - (notes.Count - notesCnt)] = new Note(notes[x]); } for (int x = notes.Count - notesCnt; x < notes.Count; x++) { notes[x] = temp[temp.Length - (x - (notes.Count - notesCnt)) - 1]; } } hasBrush = false; } break; //Consider only the first voice } int measureDuration = FlipDuration(m.Header.TimeSignature.Denominator) * m.Header.TimeSignature.Numerator; BarMaster[measureIndex].Duration = measureDuration; BarMaster[measureIndex].Index = index; index += measureDuration; _notesInMeasures.Add(notesInMeasure); } return(notes); }