public double InterpolateShapeX(double x0, double x1, double y0, double y1, double y, PitchPointShape shape) { switch (shape) { case PitchPointShape.io: return(SinEasingInOutX(x0, x1, y0, y1, y)); case PitchPointShape.i: return(SinEasingInX(x0, x1, y0, y1, y)); case PitchPointShape.o: return(SinEasingOutX(x0, x1, y0, y1, y)); default: return(LinearX(x0, x1, y0, y1, y)); } }
public ChangePitchPointShapeCommand(PitchPoint point, PitchPointShape shape) { this.Point = point; this.NewShape = shape; this.OldShape = point.shape; }
void InitPitchPointContextMenu() { pitchCxtMenu = new ContextMenu(); pitchCxtMenu.Background = Brushes.White; pitchCxtMenu.Items.Add(new MenuItem() { Header = "Ease In/Out" }); pitchCxtMenu.Items.Add(new MenuItem() { Header = "Linear" }); pitchCxtMenu.Items.Add(new MenuItem() { Header = "Ease In" }); pitchCxtMenu.Items.Add(new MenuItem() { Header = "Ease Out" }); pitchCxtMenu.Items.Add(new MenuItem() { Header = "Snap to Previous Note" }); pitchCxtMenu.Items.Add(new MenuItem() { Header = "Delete Point" }); pitchCxtMenu.Items.Add(new MenuItem() { Header = "Add Point" }); pitHitContainer = new PitchPointHitTestResultContainer(); pitchShapeDelegate = (_o, _e) => { var o = _o as MenuItem; var pitHit = pitHitContainer.Result; if (o == pitchCxtMenu.Items[4]) { DocManager.Inst.StartUndoGroup(); DocManager.Inst.ExecuteCmd(new SnapPitchPointCommand(pitHit.Note)); DocManager.Inst.EndUndoGroup(); } else if (o == pitchCxtMenu.Items[5]) { DocManager.Inst.StartUndoGroup(); DocManager.Inst.ExecuteCmd(new DeletePitchPointCommand(midiVM.Part, pitHit.Note, pitHit.Index)); DocManager.Inst.EndUndoGroup(); } else if (o == pitchCxtMenu.Items[6]) { DocManager.Inst.StartUndoGroup(); DocManager.Inst.ExecuteCmd(new AddPitchPointCommand(pitHit.Note, new PitchPoint(pitHit.X, pitHit.Y), pitHit.Index + 1)); DocManager.Inst.EndUndoGroup(); } else { PitchPointShape shape = o == pitchCxtMenu.Items[0] ? PitchPointShape.io : o == pitchCxtMenu.Items[2] ? PitchPointShape.i : o == pitchCxtMenu.Items[3] ? PitchPointShape.o : PitchPointShape.l; DocManager.Inst.StartUndoGroup(); DocManager.Inst.ExecuteCmd(new ChangePitchPointShapeCommand(pitHit.Note.PitchBend.Points[pitHit.Index], shape)); DocManager.Inst.EndUndoGroup(); } }; foreach (var item in pitchCxtMenu.Items) { var _item = item as MenuItem; if (_item != null) { _item.Click += pitchShapeDelegate; } } }
public PitchPoint(double x, double y, PitchPointShape shape = PitchPointShape.io) : base(x, y) { Shape = shape; }
public PitchPointHitInfo HitTestPitchPoint(Point mousePos) { if (!midiVM.ShowPitch) { return(null); } foreach (var note in midiVM.Part.notes) { // FIXME pitch point maybe in view while note is not. if (midiVM.NoteIsInView(note) && !note.Error) { double lastX = 0, lastY = 0; PitchPointShape lastShape = PitchPointShape.l; for (int i = 0; i < note.pitch.data.Count; i++) { var pit = note.pitch.data[i]; int posTick = note.position + Project.MillisecondToTick(pit.X); double noteNum = note.tone + pit.Y / 10; double x = midiVM.TickToCanvas(posTick); double y = midiVM.NoteNumToCanvas(noteNum) + midiVM.TrackHeight / 2; if (Math.Abs(mousePos.X - x) < 4 && Math.Abs(mousePos.Y - y) < 4) { return new PitchPointHitInfo() { Note = note, Index = i, OnPoint = true } } ; else if (mousePos.X < x && i > 0 && mousePos.X > lastX) { // Hit test curve double castY = MusicMath.InterpolateShape(lastX, x, lastY, y, mousePos.X, lastShape) - mousePos.Y; if (y >= lastY) { if (mousePos.Y - y > 3 || lastY - mousePos.Y > 3) { break; } } else { if (y - mousePos.Y > 3 || mousePos.Y - lastY > 3) { break; } } double castX = MusicMath.InterpolateShapeX(lastX, x, lastY, y, mousePos.Y, lastShape) - mousePos.X; double dis = double.IsNaN(castX) ? Math.Abs(castY) : Math.Cos(Math.Atan2(Math.Abs(castY), Math.Abs(castX))) * Math.Abs(castY); if (dis < 3) { double msX = DocManager.Inst.Project.TickToMillisecond(midiVM.CanvasToQuarter(mousePos.X) * DocManager.Inst.Project.resolution - note.position); double msY = (midiVM.CanvasToPitch(mousePos.Y) - note.tone) * 10; return(new PitchPointHitInfo() { Note = note, Index = i - 1, OnPoint = false, X = (float)msX, Y = (float)msY }); } else { break; } } lastX = x; lastY = y; lastShape = pit.shape; } } } return(null); }
public ChangePitchPointShapeCommand(PitchPoint point, PitchPointShape shape) { this.Point = point; this.NewShape = shape; this.OldShape = point.Shape; }
public PitchPointHitTestResult HitTestPitchPoint(Point mousePos) { foreach (var note in midiVM.Part.Notes) { if (midiVM.NoteIsInView(note)) // FIXME this is not enough { if (note.Error) { continue; } double lastX = 0, lastY = 0; PitchPointShape lastShape = PitchPointShape.l; for (int i = 0; i < note.PitchBend.Points.Count; i++) { var pit = note.PitchBend.Points[i]; int posTick = note.PosTick + Project.MillisecondToTick(pit.X); double noteNum = note.NoteNum + pit.Y / 10; double x = midiVM.TickToCanvas(posTick); double y = midiVM.NoteNumToCanvas(noteNum) + midiVM.TrackHeight / 2; if (Math.Abs(mousePos.X - x) < 4 && Math.Abs(mousePos.Y - y) < 4) { return new PitchPointHitTestResult() { Note = note, Index = i, OnPoint = true } } ; else if (mousePos.X < x && i > 0 && mousePos.X > lastX) { // Hit test curve var lastPit = note.PitchBend.Points[i - 1]; double castY = MusicMath.InterpolateShape(lastX, x, lastY, y, mousePos.X, lastShape) - mousePos.Y; if (y >= lastY) { if (mousePos.Y - y > 3 || lastY - mousePos.Y > 3) { break; } } else { if (y - mousePos.Y > 3 || mousePos.Y - lastY > 3) { break; } } double castX = MusicMath.InterpolateShapeX(lastX, x, lastY, y, mousePos.Y, lastShape) - mousePos.X; double dis = double.IsNaN(castX) ? Math.Abs(castY) : Math.Cos(Math.Atan2(Math.Abs(castY), Math.Abs(castX))) * Math.Abs(castY); if (dis < 3) { double msX = DocManager.Inst.Project.TickToMillisecond(midiVM.CanvasToQuarter(mousePos.X) * DocManager.Inst.Project.Resolution - note.PosTick); double msY = (midiVM.CanvasToPitch(mousePos.Y) - note.NoteNum) * 10; return(new PitchPointHitTestResult() { Note = note, Index = i - 1, OnPoint = false, X = msX, Y = msY }); } else { break; } } lastX = x; lastY = y; lastShape = pit.Shape; } } } return(null); }