SemiTone Effect_ToneChanged_affect(SemiTone tone, Time time, int delta, CaretMode mode, MusicTrack track) { if (mode.HasFlag(CaretMode.Absolute)) { return(new SemiTone(delta)); } else if (!mode.HasFlag(CaretMode.Delta)) { throw new InvalidOperationException(); } if (mode.HasFlag(CaretMode.SemiTones)) { tone += delta; } else if (mode.HasFlag(CaretMode.WholeTones)) { var keysig = track .Adornment .KeySignatures .Intersecting(time) .First() .Value; if (delta > 0) { while (delta-- > 0) { tone = keysig.Right(tone); } } else if (delta < 0) { while (delta++ < 0) { tone = keysig.Left(tone); } } } else { throw new InvalidOperationException(); } return(tone); }