private void GenerateVibrato(Note note, int noteStart, MidiNoteDuration noteDuration, int noteKey, DynamicValue dynamicValue, int channel) { int phaseLength; int bendAmplitude; switch (note.Vibrato) { case VibratoType.Slight: phaseLength = _settings.Vibrato.NoteSlightLength; bendAmplitude = _settings.Vibrato.NoteSlightAmplitude; break; case VibratoType.Wide: phaseLength = _settings.Vibrato.NoteWideLength; bendAmplitude = _settings.Vibrato.NoteWideAmplitude; break; default: return; } var track = note.Beat.Voice.Bar.Staff.Track; GenerateVibratorWithParams(track, noteStart, noteDuration.NoteOnly, phaseLength, bendAmplitude, channel); }
private void GenerateTremoloPicking(Note note, int noteStart, MidiNoteDuration noteDuration, int noteKey, DynamicValue dynamicValue, int channel) { var track = note.Beat.Voice.Bar.Staff.Track; var tpLength = note.Beat.TremoloSpeed.Value.ToTicks(); var tick = noteStart; var end = noteStart + noteDuration.UntilTieEnd; while (tick + 10 < (end)) { // only the rest on last trill play if ((tick + tpLength) >= (end)) { tpLength = (end) - tick; } _handler.AddNote(track.Index, tick, tpLength, (byte)noteKey, dynamicValue, (byte)channel); tick += tpLength; } }
private void GenerateTrill(Note note, int noteStart, MidiNoteDuration noteDuration, int noteKey, DynamicValue dynamicValue, int channel) { var track = note.Beat.Voice.Bar.Staff.Track; var trillKey = note.StringTuning + note.TrillFret; var trillLength = note.TrillSpeed.ToTicks(); var realKey = true; var tick = noteStart; var end = noteStart + noteDuration.UntilTieEnd; while (tick + 10 < (end)) { // only the rest on last trill play if ((tick + trillLength) >= (end)) { trillLength = (end) - tick; } _handler.AddNote(track.Index, tick, trillLength, (byte)(realKey ? trillKey : noteKey), dynamicValue, (byte)channel); realKey = !realKey; tick += trillLength; } }
private void GenerateFadeIn(Note note, int noteStart, MidiNoteDuration noteDuration, int noteKey, DynamicValue dynamicValue) { var track = note.Beat.Voice.Bar.Staff.Track; var endVolume = ToChannelShort(track.PlaybackInfo.Volume); var volumeFactor = (float)endVolume / noteDuration.NoteOnly; var tickStep = 120; int steps = (noteDuration.NoteOnly / tickStep); var endTick = noteStart + noteDuration.NoteOnly; for (int i = steps - 1; i >= 0; i--) { var tick = endTick - (i * tickStep); var volume = (tick - noteStart) * volumeFactor; if (i == steps - 1) { _handler.AddControlChange(track.Index, noteStart, (byte)track.PlaybackInfo.PrimaryChannel, (byte)ControllerType.VolumeCoarse, (byte)volume); _handler.AddControlChange(track.Index, noteStart, (byte)track.PlaybackInfo.SecondaryChannel, (byte)ControllerType.VolumeCoarse, (byte)volume); } _handler.AddControlChange(track.Index, tick, (byte)track.PlaybackInfo.PrimaryChannel, (byte)ControllerType.VolumeCoarse, (byte)volume); _handler.AddControlChange(track.Index, tick, (byte)track.PlaybackInfo.SecondaryChannel, (byte)ControllerType.VolumeCoarse, (byte)volume); } }
private void GenerateWhammy(Beat beat, int noteStart, MidiNoteDuration noteDuration, int noteKey, DynamicValue dynamicValue, int channel) { FastList <BendPoint> bendPoints = beat.WhammyBarPoints; var track = beat.Voice.Bar.Staff.Track; double duration = noteDuration.NoteOnly; // ensure prebends are slightly before the actual note. if (bendPoints[0].Value > 0 && !beat.IsContinuedWhammy) { noteStart--; } FastList <BendPoint> playedBendPoints = new FastList <BendPoint>(); switch (beat.WhammyBarType) { case WhammyType.Custom: playedBendPoints = bendPoints; break; case WhammyType.Dive: switch (beat.WhammyStyle) { case BendStyle.Default: playedBendPoints = bendPoints; break; case BendStyle.Gradual: playedBendPoints.Add(new BendPoint(0, bendPoints[0].Value)); playedBendPoints.Add(new BendPoint(BendPoint.MaxPosition, bendPoints[1].Value)); break; case BendStyle.Fast: GenerateSongBookWhammyOrBend(noteStart, channel, duration, track, false, new[] { bendPoints[0].Value, bendPoints[1].Value }); return; } break; case WhammyType.Dip: switch (beat.WhammyStyle) { case BendStyle.Default: playedBendPoints = bendPoints; break; case BendStyle.Gradual: playedBendPoints.Add(new BendPoint(0, bendPoints[0].Value)); playedBendPoints.Add(new BendPoint(BendPoint.MaxPosition / 2, bendPoints[1].Value)); playedBendPoints.Add(new BendPoint(BendPoint.MaxPosition, bendPoints[2].Value)); break; case BendStyle.Fast: GenerateSongBookWhammyOrBend(noteStart, channel, duration, track, true, new[] { bendPoints[0].Value, bendPoints[1].Value, bendPoints[2].Value }); return; } break; case WhammyType.Hold: playedBendPoints = bendPoints; break; case WhammyType.Predive: playedBendPoints = bendPoints; break; case WhammyType.PrediveDive: switch (beat.WhammyStyle) { case BendStyle.Default: playedBendPoints = bendPoints; break; case BendStyle.Gradual: playedBendPoints.Add(new BendPoint(0, bendPoints[0].Value)); playedBendPoints.Add(new BendPoint(BendPoint.MaxPosition / 2, bendPoints[0].Value)); playedBendPoints.Add(new BendPoint(BendPoint.MaxPosition, bendPoints[1].Value)); break; case BendStyle.Fast: var preDiveValue = DefaultBend + (bendPoints[0].Value * DefaultBendSemitone); _handler.AddBend(track.Index, noteStart, (byte)channel, (byte)preDiveValue); GenerateSongBookWhammyOrBend(noteStart, channel, duration, track, false, new[] { bendPoints[0].Value, bendPoints[1].Value }); return; } break; } GenerateWhammyOrBend(noteStart, channel, duration, playedBendPoints, track); }
private void GenerateBend(Note note, int noteStart, MidiNoteDuration noteDuration, int noteKey, DynamicValue dynamicValue, int channel) { FastList <BendPoint> bendPoints = note.BendPoints; var track = note.Beat.Voice.Bar.Staff.Track; // Bends are spread across all tied notes unless they have a bend on their own. double duration; if (note.IsTieOrigin && (_settings == null || _settings.ExtendBendArrowsOnTiedNotes)) { var endNote = note; while (endNote.IsTieOrigin && !endNote.TieDestination.HasBend) { endNote = endNote.TieDestination; } duration = endNote.Beat.AbsolutePlaybackStart - note.Beat.AbsolutePlaybackStart + GetNoteDuration(endNote, endNote.Beat.PlaybackDuration).NoteOnly; } else { duration = noteDuration.NoteOnly; } // ensure prebends are slightly before the actual note. if (bendPoints[0].Value > 0 && !note.IsContinuedBend) { noteStart--; } FastList <BendPoint> playedBendPoints = new FastList <BendPoint>(); switch (note.BendType) { case BendType.Custom: playedBendPoints = bendPoints; break; case BendType.Bend: case BendType.Release: switch (note.BendStyle) { case BendStyle.Default: playedBendPoints = bendPoints; break; case BendStyle.Gradual: playedBendPoints.Add(new BendPoint(0, note.BendPoints[0].Value)); playedBendPoints.Add(new BendPoint(BendPoint.MaxPosition, note.BendPoints[1].Value)); break; case BendStyle.Fast: if (note.Beat.GraceType == GraceType.BendGrace) { GenerateSongBookWhammyOrBend(noteStart, channel, duration, track, true, new[] { note.BendPoints[0].Value, note.BendPoints[1].Value }); } else { GenerateSongBookWhammyOrBend(noteStart, channel, duration, track, false, new[] { note.BendPoints[0].Value, note.BendPoints[1].Value }); } return; } break; case BendType.BendRelease: switch (note.BendStyle) { case BendStyle.Default: playedBendPoints = bendPoints; break; case BendStyle.Gradual: playedBendPoints.Add(new BendPoint(0, note.BendPoints[0].Value)); playedBendPoints.Add(new BendPoint(BendPoint.MaxPosition / 2, note.BendPoints[1].Value)); playedBendPoints.Add(new BendPoint(BendPoint.MaxPosition, note.BendPoints[2].Value)); break; case BendStyle.Fast: GenerateSongBookWhammyOrBend(noteStart, channel, duration, track, false, new[] { note.BendPoints[0].Value, note.BendPoints[1].Value, note.BendPoints[2].Value }); return; } break; case BendType.Hold: playedBendPoints = bendPoints; break; case BendType.Prebend: playedBendPoints = bendPoints; break; case BendType.PrebendBend: switch (note.BendStyle) { case BendStyle.Default: playedBendPoints = bendPoints; break; case BendStyle.Gradual: playedBendPoints.Add(new BendPoint(0, note.BendPoints[0].Value)); playedBendPoints.Add(new BendPoint(BendPoint.MaxPosition / 2, note.BendPoints[0].Value)); playedBendPoints.Add(new BendPoint(BendPoint.MaxPosition, note.BendPoints[1].Value)); break; case BendStyle.Fast: var preBendValue = DefaultBend + (note.BendPoints[0].Value * DefaultBendSemitone); _handler.AddBend(track.Index, noteStart, (byte)channel, (byte)preBendValue); GenerateSongBookWhammyOrBend(noteStart, channel, duration, track, false, new[] { note.BendPoints[0].Value, note.BendPoints[1].Value }); return; } break; case BendType.PrebendRelease: switch (note.BendStyle) { case BendStyle.Default: playedBendPoints = bendPoints; break; case BendStyle.Gradual: playedBendPoints.Add(new BendPoint(0, note.BendPoints[0].Value)); playedBendPoints.Add(new BendPoint(BendPoint.MaxPosition / 2, note.BendPoints[0].Value)); playedBendPoints.Add(new BendPoint(BendPoint.MaxPosition, note.BendPoints[1].Value)); break; case BendStyle.Fast: var preBendValue = DefaultBend + (note.BendPoints[0].Value * DefaultBendSemitone); _handler.AddBend(track.Index, noteStart, (byte)channel, (byte)preBendValue); GenerateSongBookWhammyOrBend(noteStart, channel, duration, track, true, new[] { note.BendPoints[0].Value, note.BendPoints[1].Value }); return; } break; } GenerateWhammyOrBend(noteStart, channel, duration, playedBendPoints, track); }
private void GenerateSlide(Note note, int noteStart, MidiNoteDuration noteDuration, int noteKey, DynamicValue dynamicValue, int channel) { // TODO }
private MidiNoteDuration GetNoteDuration(Note note, int duration) { var durationWithEffects = new MidiNoteDuration(); durationWithEffects.NoteOnly = duration; durationWithEffects.UntilTieEnd = duration; durationWithEffects.LetRingEnd = duration; if (note.IsDead) { durationWithEffects.NoteOnly = ApplyStaticDuration(DefaultDurationDead, duration); durationWithEffects.UntilTieEnd = durationWithEffects.NoteOnly; durationWithEffects.LetRingEnd = durationWithEffects.NoteOnly; return(durationWithEffects); } if (note.IsPalmMute) { durationWithEffects.NoteOnly = ApplyStaticDuration(DefaultDurationPalmMute, duration); durationWithEffects.UntilTieEnd = durationWithEffects.NoteOnly; durationWithEffects.LetRingEnd = durationWithEffects.NoteOnly; return(durationWithEffects); } if (note.IsStaccato) { durationWithEffects.NoteOnly = (duration / 2); durationWithEffects.UntilTieEnd = durationWithEffects.NoteOnly; durationWithEffects.LetRingEnd = durationWithEffects.NoteOnly; return(durationWithEffects); } if (note.IsTieOrigin) { var endNote = note.TieDestination; // for the initial start of the tie calculate absolute duration from start to end note if (endNote != null) { if (!note.IsTieDestination) { var startTick = note.Beat.AbsolutePlaybackStart; var tieDestinationDuration = GetNoteDuration(endNote, endNote.Beat.PlaybackDuration); var endTick = endNote.Beat.AbsolutePlaybackStart + tieDestinationDuration.UntilTieEnd; durationWithEffects.UntilTieEnd = endTick - startTick; } else { // for continuing ties, take the current duration + the one from the destination // this branch will be entered as part of the recusion of the if branch var tieDestinationDuration = GetNoteDuration(endNote, endNote.Beat.PlaybackDuration); durationWithEffects.UntilTieEnd = duration + tieDestinationDuration.UntilTieEnd; } } } if (note.IsLetRing && _settings.DisplayMode == DisplayMode.GuitarPro) { // LetRing ends when: // - rest Beat lastLetRingBeat = note.Beat; var letRingEnd = 0; var maxDuration = note.Beat.Voice.Bar.MasterBar.CalculateDuration(); while (lastLetRingBeat.NextBeat != null) { var next = lastLetRingBeat.NextBeat; if (next.IsRest) { break; } // note on the same string if (note.IsStringed && next.HasNoteOnString(note.String)) { break; } lastLetRingBeat = lastLetRingBeat.NextBeat; letRingEnd = (lastLetRingBeat.AbsolutePlaybackStart - note.Beat.AbsolutePlaybackStart) + lastLetRingBeat.PlaybackDuration; if (letRingEnd > maxDuration) { letRingEnd = maxDuration; break; } } if (lastLetRingBeat == note.Beat) { durationWithEffects.LetRingEnd = duration; } else { durationWithEffects.LetRingEnd = letRingEnd; } } else { durationWithEffects.LetRingEnd = durationWithEffects.UntilTieEnd; } return(durationWithEffects); }
private void GenerateBend(Note note, int noteStart, MidiNoteDuration noteDuration, int noteKey, DynamicValue dynamicValue, int channel) { FastList <BendPoint> bendPoints = note.BendPoints; var track = note.Beat.Voice.Bar.Staff.Track; // if bend is extended on next tied note, we directly bend to the final bend value int?finalBendValue = null; // Bends are spread across all tied notes unless they have a bend on their own. double duration; if (note.IsTieOrigin && (_settings == null || _settings.ExtendBendArrowsOnTiedNotes)) { var endNote = note; while (endNote.IsTieOrigin && !endNote.TieDestination.HasBend) { endNote = endNote.TieDestination; } duration = endNote.Beat.AbsolutePlaybackStart - note.Beat.AbsolutePlaybackStart + GetNoteDuration(endNote, endNote.Beat.PlaybackDuration).NoteOnly; } // if current note is a grace note with bend and tie, we can reach into next note else if (note.IsTieOrigin && note.Beat.GraceType != GraceType.None) { switch (note.TieDestination.BendType) { case BendType.Bend: case BendType.BendRelease: case BendType.PrebendBend: finalBendValue = note.TieDestination.BendPoints[1].Value; break; case BendType.Prebend: case BendType.PrebendRelease: finalBendValue = note.TieDestination.BendPoints[0].Value; break; } if (_settings == null) { duration = noteDuration.NoteOnly; } else { duration = Math.Max(noteDuration.NoteOnly, MidiUtils.MillisToTicks(_settings.SongBookBendDuration, _currentTempo)); } } else { duration = noteDuration.NoteOnly; } // ensure prebends are slightly before the actual note. if (bendPoints[0].Value > 0 && !note.IsContinuedBend) { noteStart--; } var bendDuration = _settings == null ? duration : Math.Min(duration, MidiUtils.MillisToTicks(_settings.SongBookBendDuration, _currentTempo)); FastList <BendPoint> playedBendPoints = new FastList <BendPoint>(); switch (note.BendType) { case BendType.Custom: playedBendPoints = bendPoints; break; case BendType.Bend: case BendType.Release: switch (note.BendStyle) { case BendStyle.Default: playedBendPoints = bendPoints; break; case BendStyle.Gradual: playedBendPoints.Add(new BendPoint(0, note.BendPoints[0].Value)); if (finalBendValue == null || finalBendValue.Value < note.BendPoints[1].Value) { finalBendValue = note.BendPoints[1].Value; } playedBendPoints.Add(new BendPoint(BendPoint.MaxPosition, finalBendValue.Value)); break; case BendStyle.Fast: if (finalBendValue == null || finalBendValue.Value < note.BendPoints[1].Value) { finalBendValue = note.BendPoints[1].Value; } if (note.Beat.GraceType == GraceType.BendGrace) { GenerateSongBookWhammyOrBend(noteStart, channel, duration, track, true, new[] { note.BendPoints[0].Value, finalBendValue.Value }, bendDuration); } else { GenerateSongBookWhammyOrBend(noteStart, channel, duration, track, false, new[] { note.BendPoints[0].Value, finalBendValue.Value }, bendDuration); } return; } break; case BendType.BendRelease: switch (note.BendStyle) { case BendStyle.Default: playedBendPoints = bendPoints; break; case BendStyle.Gradual: playedBendPoints.Add(new BendPoint(0, note.BendPoints[0].Value)); playedBendPoints.Add(new BendPoint(BendPoint.MaxPosition / 2, note.BendPoints[1].Value)); playedBendPoints.Add(new BendPoint(BendPoint.MaxPosition, note.BendPoints[2].Value)); break; case BendStyle.Fast: GenerateSongBookWhammyOrBend(noteStart, channel, duration, track, false, new[] { note.BendPoints[0].Value, note.BendPoints[1].Value, note.BendPoints[2].Value }, bendDuration); return; } break; case BendType.Hold: playedBendPoints = bendPoints; break; case BendType.Prebend: playedBendPoints = bendPoints; break; case BendType.PrebendBend: switch (note.BendStyle) { case BendStyle.Default: playedBendPoints = bendPoints; break; case BendStyle.Gradual: playedBendPoints.Add(new BendPoint(0, note.BendPoints[0].Value)); playedBendPoints.Add(new BendPoint(BendPoint.MaxPosition, note.BendPoints[1].Value)); break; case BendStyle.Fast: var preBendValue = DefaultBend + (note.BendPoints[0].Value * DefaultBendSemitone); _handler.AddBend(track.Index, noteStart, (byte)channel, (int)preBendValue); if (finalBendValue == null || finalBendValue.Value < note.BendPoints[1].Value) { finalBendValue = note.BendPoints[1].Value; } GenerateSongBookWhammyOrBend(noteStart, channel, duration, track, false, new[] { note.BendPoints[0].Value, finalBendValue.Value }, bendDuration); return; } break; case BendType.PrebendRelease: switch (note.BendStyle) { case BendStyle.Default: playedBendPoints = bendPoints; break; case BendStyle.Gradual: playedBendPoints.Add(new BendPoint(0, note.BendPoints[0].Value)); playedBendPoints.Add(new BendPoint(BendPoint.MaxPosition, note.BendPoints[1].Value)); break; case BendStyle.Fast: var preBendValue = DefaultBend + (note.BendPoints[0].Value * DefaultBendSemitone); _handler.AddBend(track.Index, noteStart, (byte)channel, (int)preBendValue); GenerateSongBookWhammyOrBend(noteStart, channel, duration, track, false, new[] { note.BendPoints[0].Value, note.BendPoints[1].Value }, bendDuration); return; } break; } GenerateWhammyOrBend(noteStart, channel, duration, playedBendPoints, track); }