public int[] BuildPitch(PitchInfo pitchInfo) { var pitches = new List <int>(); var interv = Settings.Current.IntervalTick; var i = -1; double xl = 0; // x local var dir = -99; // up or down double y = -99; // point value double xk = -99; // sin width double yk = -99; // sin height double C = -99; // normalize to zero bool IsNextPointTime; bool IsLastPoint; int nextX; int thisX; for (var x = pitchInfo.Start; x <= pitchInfo.End; x += interv) { // only S shape is allowed nextX = (int)pitchInfo.PitchPoints[i + 1].X; thisX = x; IsNextPointTime = thisX < 0 ? thisX + interv >= nextX : thisX + interv >= nextX; IsLastPoint = i + 2 == pitchInfo.PitchPoints.Length; while (IsNextPointTime && !IsLastPoint || i < 0) { // goto next pitch points pair i++; xk = pitchInfo.PitchPoints[i + 1].X - pitchInfo.PitchPoints[i].X; yk = pitchInfo.PitchPoints[i + 1].Y - pitchInfo.PitchPoints[i].Y; dir = pitchInfo.PitchPoints[i + 1].Y > pitchInfo.PitchPoints[i].Y ? 1 : -1; dir = pitchInfo.PitchPoints[i + 1].Y == pitchInfo.PitchPoints[i].Y ? 0 : dir; C = pitchInfo.PitchPoints[i + 1].Y; xl = 0; nextX = (int)(pitchInfo.PitchPoints[i + 1].X / interv - 0.5 * Settings.Current.IntervalMs); nextX -= (int)(nextX % Settings.Current.IntervalMs); thisX = (int)Math.Ceiling((double)x / interv); IsNextPointTime = thisX >= nextX; IsLastPoint = i + 2 == pitchInfo.PitchPoints.Length; } if (dir == -99) { throw new Exception(); } yk = Math.Round(yk, 3); var X = Math.Abs(xk) < 5 ? 0 : 1 / xk * 10 * xl / Math.PI; y = -yk * (0.5 * Math.Cos(X) + 0.5) + C; y *= 10; pitches.Add((int)Math.Round(y)); xl += interv; } //if (i < pitchInfo.PitchPoints.Length - 2) // throw new Exception("Some points was not processed"); return(pitches.ToArray()); }
public PitchInfo BuildPitchInfo(Note note, Note prevNote, Note nextNote) { var pitchInfo = new PitchInfo(); var autoPitchLength = 40; var autoPitchOffset = -20; var firstNoteRaise = 10; var oto = note.SafeOto; var pps = new List <PitchPoint>(); foreach (var pp in note.PitchBend.Points) { pps.Add(pp); } if (pps.Count == 0) { var offsetY = prevNote == null ? firstNoteRaise : GetPitchDiff(note.NoteNum, prevNote.NoteNum); pps.Add(new PitchPoint(MusicMath.Current.TickToMillisecond(autoPitchOffset), -offsetY)); pps.Add(new PitchPoint(MusicMath.Current.TickToMillisecond(autoPitchOffset + autoPitchLength), 0)); note.PitchBend.Data = pps; } var cutoffFromNext = nextNote != null ? nextNote.StraightPre : 0; // end and start ms var startMs = pps.First().X < -oto.Preutter ? pps.First().X : -oto.Preutter; double endMs = MusicMath.Current.TickToMillisecond(note.FinalLength) - cutoffFromNext; // if not all the length involved, add end and/or start pitch points if (pps.First().X > startMs) { pps.Insert(0, new PitchPoint(startMs, pps.First().Y)); } if (pps.Last().X < endMs) { pps.Add(new PitchPoint(endMs, pps.Last().Y)); } var start = (int)MusicMath.Current.SnapMs(pps.First().X); var end = (int)MusicMath.Current.SnapMs(pps.Last().X); // combine all pitchInfo.Start = start; pitchInfo.End = end; pitchInfo.PitchPoints = pps.ToArray(); return(pitchInfo); }