Skip to content

Commit

Permalink
mainブランチマージ後の修正
Browse files Browse the repository at this point in the history
  • Loading branch information
sigprogramming committed Nov 21, 2024
1 parent 2e44280 commit c08b4e6
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 129 deletions.
6 changes: 3 additions & 3 deletions src/components/Sing/ScoreSequencer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ import {
useCommandOrControlKey,
useShiftKey,
} from "@/composables/useModifierKey";
import { applyGaussianFilter, Interpolate } from "@/sing/utility";
import { applyGaussianFilter, interpolateLinear } from "@/sing/utility";
import { useLyricInput } from "@/composables/useLyricInput";
import { useCursorState, CursorState } from "@/composables/useCursorState";
import { ExhaustiveError } from "@/type/utility";
Expand Down Expand Up @@ -667,7 +667,7 @@ const previewDrawPitch = () => {
} else if (cursorFrame < prevCursorPos.frame) {
for (let i = cursorFrame; i <= prevCursorPos.frame; i++) {
tempPitchEdit.data[i - tempPitchEdit.startFrame] = Math.exp(
Interpolate.linear(
interpolateLinear(
{ x: cursorFrame, y: Math.log(cursorFrequency) },
{ x: prevCursorPos.frame, y: Math.log(prevCursorPos.frequency) },
i,
Expand All @@ -677,7 +677,7 @@ const previewDrawPitch = () => {
} else {
for (let i = prevCursorPos.frame; i <= cursorFrame; i++) {
tempPitchEdit.data[i - tempPitchEdit.startFrame] = Math.exp(
Interpolate.linear(
interpolateLinear(
{ x: prevCursorPos.frame, y: Math.log(prevCursorPos.frequency) },
{ x: cursorFrame, y: Math.log(cursorFrequency) },
i,
Expand Down
6 changes: 2 additions & 4 deletions src/components/Sing/SequencerPitch.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import {
} from "@/composables/onMountOrActivate";
import { ExhaustiveError } from "@/type/utility";
import { createLogger } from "@/domain/frontend/log";
import { Interpolate, iterativeEndPointFit } from "@/sing/utility";
import { interpolatePchip, iterativeEndPointFit } from "@/sing/utility";
import { Color } from "@/sing/graphics/color";
import { Points } from "@/sing/graphics/points";
import { getLast } from "@/sing/utility";
Expand Down Expand Up @@ -416,8 +416,6 @@ const generateOriginalPitchData = () => {
};
const generatePitchEditData = () => {
const frameRate = editorFrameRate.value;
const tempData = [...pitchEditData.value];
// プレビュー中のピッチ編集があれば、適用する
if (previewPitchEdit.value != undefined) {
Expand Down Expand Up @@ -520,7 +518,7 @@ watch(
xValues.push(i);
}
xValues.push(maxX);
const yValues = Interpolate.catmullRom(points2, xValues);
const yValues = interpolatePchip(points2, xValues);
const interpPitchData: PitchData = {
ticksArray: xValues,
data: yValues.map((value) => noteNumberToFrequency(value)),
Expand Down
243 changes: 124 additions & 119 deletions src/sing/utility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,142 +22,147 @@ export function calculateDistanceFromPointToLine(
);
}

export class Interpolate {
static linear(
p0: { x: number; y: number },
p1: { x: number; y: number },
x: number,
) {
if (p1.x <= p0.x) {
throw new Error("p1.x must be greater than p0.x.");
}
const m = (p1.y - p0.y) / (p1.x - p0.x);
return p0.y + (x - p0.x) * m;
export function interpolateLinear(
p0: { x: number; y: number },
p1: { x: number; y: number },
x: number,
) {
if (p1.x <= p0.x) {
throw new Error("p1.x must be greater than p0.x.");
}
const m = (p1.y - p0.y) / (p1.x - p0.x);
return p0.y + (x - p0.x) * m;
}

static cubicHermite(
p0: { x: number; y: number },
m0: number,
p1: { x: number; y: number },
m1: number,
x: number,
) {
const dx = p1.x - p0.x;
const t = (x - p0.x) / dx;
const h0 = 2 * t ** 3 - 3 * t ** 2 + 1;
const h1 = t ** 3 - 2 * t ** 2 + t;
const h2 = -2 * t ** 3 + 3 * t ** 2;
const h3 = t ** 3 - t ** 2;
return p0.y * h0 + m0 * dx * h1 + p1.y * h2 + m1 * dx * h3;
}
export function interpolateCubicHermite(
p0: { x: number; y: number },
m0: number,
p1: { x: number; y: number },
m1: number,
x: number,
) {
const dx = p1.x - p0.x;
const t = (x - p0.x) / dx;
const h0 = 2 * t ** 3 - 3 * t ** 2 + 1;
const h1 = t ** 3 - 2 * t ** 2 + t;
const h2 = -2 * t ** 3 + 3 * t ** 2;
const h3 = t ** 3 - t ** 2;
return p0.y * h0 + m0 * dx * h1 + p1.y * h2 + m1 * dx * h3;
}

static catmullRom(points: { x: number; y: number }[], xValues: number[]) {
if (points.length < 2) {
throw new Error("points.length must be at least 2.");
}
const n = points.length;
const firstP = points[0];
const lastP = points[n - 1];
export function interpolateCubicSpline(
points: { x: number; y: number }[],
xValues: number[],
) {
if (points.length < 2) {
throw new Error("points.length must be at least 2.");
}
const n = points.length;
const firstP = points[0];
const lastP = points[n - 1];

const mValues: number[] = [];
for (let i = 0; i < n; i++) {
const p0 = points[Math.max(0, i - 1)];
const p1 = points[Math.min(n - 1, i + 1)];
const m = (p1.y - p0.y) / (p1.x - p0.x);
mValues.push(m);
}
const mValues: number[] = [];
for (let i = 0; i < n; i++) {
const p0 = points[Math.max(0, i - 1)];
const p1 = points[Math.min(n - 1, i + 1)];
const m = (p1.y - p0.y) / (p1.x - p0.x);
mValues.push(m);
}

const yValues: number[] = [];
for (const x of xValues) {
if (x < firstP.x) {
const m = mValues[0];
const y = firstP.y + (x - firstP.x) * m;
yValues.push(y);
} else if (x >= lastP.x) {
const m = mValues[n - 1];
const y = lastP.y + (x - lastP.x) * m;
yValues.push(y);
} else {
for (let i = 0; i < n - 1; i++) {
if (x < points[i + 1].x) {
const p0 = points[i];
const p1 = points[i + 1];
const m0 = mValues[i];
const m1 = mValues[i + 1];
const y = this.cubicHermite(p0, m0, p1, m1, x);
yValues.push(y);
break;
}
const yValues: number[] = [];
for (const x of xValues) {
if (x < firstP.x) {
const m = mValues[0];
const y = firstP.y + (x - firstP.x) * m;
yValues.push(y);
} else if (x >= lastP.x) {
const m = mValues[n - 1];
const y = lastP.y + (x - lastP.x) * m;
yValues.push(y);
} else {
for (let i = 0; i < n - 1; i++) {
if (x < points[i + 1].x) {
const p0 = points[i];
const p1 = points[i + 1];
const m0 = mValues[i];
const m1 = mValues[i + 1];
const y = interpolateCubicHermite(p0, m0, p1, m1, x);
yValues.push(y);
break;
}
}
}
return yValues;
}
return yValues;
}

static pchip(points: { x: number; y: number }[], xValues: number[]) {
if (points.length < 2) {
throw new Error("points.length must be at least 2.");
}
const n = points.length;
const firstP = points[0];
const lastP = points[n - 1];
export function interpolatePchip(
points: { x: number; y: number }[],
xValues: number[],
) {
if (points.length < 2) {
throw new Error("points.length must be at least 2.");
}
const n = points.length;
const firstP = points[0];
const lastP = points[n - 1];

const mValues: number[] = [];
for (let i = 0; i < n; i++) {
const p0 = points[Math.max(0, i - 1)];
const p1 = points[i];
const p2 = points[Math.min(n - 1, i + 1)];
const dx = p2.x - p0.x;
const dy0 = p1.y - p0.y;
const dy1 = p2.y - p1.y;
const m = dy0 * dy1 <= 0 ? 0 : (dy0 + dy1) / dx;
mValues.push(m);
}
for (let i = 0; i < n - 1; i++) {
const m0 = mValues[i];
const m1 = mValues[i + 1];
const p0 = points[i];
const p1 = points[i + 1];
const dx = p1.x - p0.x;
const dy = p1.y - p0.y;
if (dy !== 0) {
const d = dy / dx;
const a = m0 / d;
const b = m1 / d;
const t = 3 / Math.sqrt(a * a + b * b);
if (t < 1) {
mValues[i] = t * a * d;
mValues[i + 1] = t * b * d;
}
const mValues: number[] = [];
for (let i = 0; i < n; i++) {
const p0 = points[Math.max(0, i - 1)];
const p1 = points[i];
const p2 = points[Math.min(n - 1, i + 1)];
const dx = p2.x - p0.x;
const dy0 = p1.y - p0.y;
const dy1 = p2.y - p1.y;
const m = dy0 * dy1 <= 0 ? 0 : (dy0 + dy1) / dx;
mValues.push(m);
}
for (let i = 0; i < n - 1; i++) {
const m0 = mValues[i];
const m1 = mValues[i + 1];
const p0 = points[i];
const p1 = points[i + 1];
const dx = p1.x - p0.x;
const dy = p1.y - p0.y;
if (dy !== 0) {
const d = dy / dx;
const a = m0 / d;
const b = m1 / d;
const n = Math.sqrt(a * a + b * b);
if (n > 3) {
const t = 3 / n;
mValues[i] = t * a * d;
mValues[i + 1] = t * b * d;
}
}
}

const yValues: number[] = [];
for (const x of xValues) {
if (x < firstP.x) {
const m = mValues[0];
const y = firstP.y + (x - firstP.x) * m;
yValues.push(y);
} else if (x >= lastP.x) {
const m = mValues[n - 1];
const y = lastP.y + (x - lastP.x) * m;
yValues.push(y);
} else {
for (let i = 0; i < n - 1; i++) {
if (x < points[i + 1].x) {
const p0 = points[i];
const p1 = points[i + 1];
const m0 = mValues[i];
const m1 = mValues[i + 1];
const y = this.cubicHermite(p0, m0, p1, m1, x);
yValues.push(y);
break;
}
const yValues: number[] = [];
for (const x of xValues) {
if (x < firstP.x) {
const m = mValues[0];
const y = firstP.y + (x - firstP.x) * m;
yValues.push(y);
} else if (x >= lastP.x) {
const m = mValues[n - 1];
const y = lastP.y + (x - lastP.x) * m;
yValues.push(y);
} else {
for (let i = 0; i < n - 1; i++) {
if (x < points[i + 1].x) {
const p0 = points[i];
const p1 = points[i + 1];
const m0 = mValues[i];
const m1 = mValues[i + 1];
const y = interpolateCubicHermite(p0, m0, p1, m1, x);
yValues.push(y);
break;
}
}
}
return yValues;
}
return yValues;
}

export function differentiate(yValues: number[]) {
Expand Down Expand Up @@ -196,7 +201,7 @@ export function iterativeEndPointFit(
let farthestPointD = 0;
for (let i = 1; i < pointsToProcess.length - 1; i++) {
const p2 = pointsToProcess[i];
const d = Math.abs(p2.y - Interpolate.linear(p0, p1, p2.x));
const d = Math.abs(p2.y - interpolateLinear(p0, p1, p2.x));
if (d > farthestPointD) {
farthestPointD = d;
farthestPointIndex = i;
Expand Down
6 changes: 3 additions & 3 deletions src/store/singing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ import {
AnimationTimer,
calculateHash,
createPromiseThatResolvesWhen,
Interpolate,
interpolateLinear,
round,
} from "@/sing/utility";
import { getWorkaroundKeyRangeAdjustment } from "@/sing/workaroundKeyRangeAdjustment";
Expand Down Expand Up @@ -378,10 +378,10 @@ const muteLastPauSection = (
volume[lastPauStartFrame] *= 0.5;
} else {
for (let i = 0; i < fadeOutFrameLength; i++) {
volume[lastPauStartFrame + i] *= Interpolate.linear(
volume[lastPauStartFrame + i] *= interpolateLinear(
{ x: 0, y: 1 },
{ x: fadeOutFrameLength - 1, y: 0 },
i
i,
);
}
}
Expand Down

0 comments on commit c08b4e6

Please sign in to comment.