Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pitch Baking: fix PITD erasing region misplaced, process the whole part by default #708

Merged
merged 2 commits into from
May 21, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 29 additions & 14 deletions OpenUtau.Core/Editing/NoteBatchEdits.cs
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,8 @@ PitchPointShape DetermineShape(Point start, Point middle, Point end){
* Wikipedia: https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm
* Implementation reference: https://rosettacode.org/wiki/Ramer-Douglas-Peucker_line_simplification
* */
//perpendicularDistance is replaced with deltaY, because the units of X and Y are different.
//result doesn't contain the last point to enhance performance in recursion
List<Point> simplifyShape(List<Point> pointList, Double epsilon) {
if (pointList.Count <= 2) {
return pointList;
Expand Down Expand Up @@ -362,15 +364,14 @@ List<Point> simplifyShape(List<Point> pointList, Double epsilon) {
var recResults2 = simplifyShape(pointList.GetRange(index, pointList.Count - index), epsilon);

// Build the result list
results.AddRange(recResults1.GetRange(0, recResults1.Count - 1));
results.AddRange(recResults1);
results.AddRange(recResults2);
if (results.Count < 2) {
throw new Exception("Problem assembling output");
}
} else {
//Just return start and end points
//Just return the start point
results.Add(pointList[0].ChangeShape(shape));
results.Add(pointList[end]);
}
return results;
}
Expand Down Expand Up @@ -424,7 +425,18 @@ public void Run(UProject project, UVoicePart part, List<UNote> selectedNotes, Do
).ToList();

//Reduce pitch point
points = simplifyShape(points, 10);
var mustIncludeIndices = phrase.notes
.SelectMany(n => new[] {
n.position,
n.duration>160 ? n.end-80 : n.position+n.duration/2 })
.Select(t=>(t-pitchStart)/pitchInterval)
.Prepend(0)
.Append(points.Count-1)
.ToList();
//pairwise(mustIncludePointIndices)
points = mustIncludeIndices.Zip(mustIncludeIndices.Skip(1),
(a, b) => simplifyShape(points.GetRange(a,b-a),10))
.SelectMany(x=>x).Append(points[^1]).ToList();

//determine where to distribute pitch point
int idx = 0;
Expand Down Expand Up @@ -459,7 +471,7 @@ public void Run(UProject project, UVoicePart part, List<UNote> selectedNotes, Do
}
}
adjusted_boundaries[^1] = note_boundaries[^1];
//distribute pitch point
//distribute pitch point to each note
foreach(int i in Enumerable.Range(0,phrase.notes.Length)) {
var note = phrase.notes[i];
var pitch = points.GetRange(adjusted_boundaries[i]-2,adjusted_boundaries[i + 1]-(adjusted_boundaries[i]-2))
Expand All @@ -476,7 +488,8 @@ public void Run(UProject project, UVoicePart part, List<UNote> selectedNotes, Do
}
}
docManager.StartUndoGroup(true);
foreach(var note in selectedNotes) {
//Apply pitch points to notes
foreach(var note in notes) {
if (pitchPointsPerNote.TryGetValue(note.position, out var tickRangeAndPitch)) {
var pitch = tickRangeAndPitch.Item3;
docManager.ExecuteCmd(new ResetPitchPointsCommand(part, note));
Expand All @@ -492,21 +505,23 @@ public void Run(UProject project, UVoicePart part, List<UNote> selectedNotes, Do

}
}
foreach(var note in selectedNotes) {
//Erase PITD curve that has been converted to pitch points
foreach(var note in notes) {
if (pitchPointsPerNote.TryGetValue(note.position, out var tickRangeAndPitch)) {
var start = tickRangeAndPitch.Item1 - part.position;
var end = tickRangeAndPitch.Item2 - part.position;
docManager.ExecuteCmd(new SetCurveCommand(project, part, Format.Ustx.PITD,
tickRangeAndPitch.Item1, 0,
tickRangeAndPitch.Item1, 0));
start, 0,
start, 0));
docManager.ExecuteCmd(new SetCurveCommand(project, part, Format.Ustx.PITD,
tickRangeAndPitch.Item2, 0,
tickRangeAndPitch.Item2, 0));
end, 0,
end, 0));
docManager.ExecuteCmd(new SetCurveCommand(project, part, Format.Ustx.PITD,
tickRangeAndPitch.Item1, 0,
tickRangeAndPitch.Item2, 0));
start, 0,
end, 0));
}
}
docManager.EndUndoGroup();

}
}
}