Example #1
0
 public BeatStroke(BeatStrokeDirections d, int v, float s)
 {
     Direction = d;
     Value     = v;
     StartTime = s;
 }
Example #2
0
        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);
        }