Skip to content

Commit

Permalink
一旦コミット
Browse files Browse the repository at this point in the history
  • Loading branch information
sigprogramming committed Nov 20, 2024
1 parent 867e266 commit 2e44280
Show file tree
Hide file tree
Showing 4 changed files with 282 additions and 146 deletions.
12 changes: 4 additions & 8 deletions src/components/Sing/ScoreSequencer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -668,10 +668,8 @@ const previewDrawPitch = () => {
for (let i = cursorFrame; i <= prevCursorPos.frame; i++) {
tempPitchEdit.data[i - tempPitchEdit.startFrame] = Math.exp(
Interpolate.linear(
cursorFrame,
Math.log(cursorFrequency),
prevCursorPos.frame,
Math.log(prevCursorPos.frequency),
{ x: cursorFrame, y: Math.log(cursorFrequency) },
{ x: prevCursorPos.frame, y: Math.log(prevCursorPos.frequency) },
i,
),
);
Expand All @@ -680,10 +678,8 @@ const previewDrawPitch = () => {
for (let i = prevCursorPos.frame; i <= cursorFrame; i++) {
tempPitchEdit.data[i - tempPitchEdit.startFrame] = Math.exp(
Interpolate.linear(
prevCursorPos.frame,
Math.log(prevCursorPos.frequency),
cursorFrame,
Math.log(cursorFrequency),
{ x: prevCursorPos.frame, y: Math.log(prevCursorPos.frequency) },
{ x: cursorFrame, y: Math.log(cursorFrequency) },
i,
),
);
Expand Down
198 changes: 103 additions & 95 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 } from "@/sing/utility";
import { Interpolate, 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 @@ -120,14 +120,14 @@ const pitchEditLine: PitchLine = {
lineStripMap: new Map(),
};
const interpOriginalPitchLine: PitchLine = {
color: new Color(171, 199, 201, 255),
color: ref(new Color(171, 199, 201, 255)),
width: 1.5,
pitchDataMap: new Map(),
lineStripMap: new Map(),
};
const interpOriginalPitchKnots: PitchKnots = {
color: new Color(149, 188, 207, 255),
radius: 2,
color: new Color(212, 154, 148, 255),
radius: 3,
};
const canvasContainer = ref<HTMLElement | null>(null);
Expand All @@ -137,12 +137,14 @@ let canvasHeight: number | undefined;
let renderer: PIXI.Renderer | undefined;
let stage: PIXI.Container | undefined;
let lineStripsContainer: PIXI.Container | undefined;
let pointsContainer: PIXI.Container | undefined;
let requestId: number | undefined;
let renderInNextFrame = false;
const updateLineStrips = (pitchLine: PitchLine) => {
if (stage == undefined) {
throw new Error("stage is undefined.");
if (lineStripsContainer == undefined) {
throw new Error("lineStripsContainer is undefined.");
}
if (canvasWidth == undefined) {
throw new Error("canvasWidth is undefined.");
Expand All @@ -159,7 +161,7 @@ const updateLineStrips = (pitchLine: PitchLine) => {
// 無くなったピッチデータを調べて、そのピッチデータに対応するLineStripを削除する
for (const [key, lineStrip] of pitchLine.lineStripMap) {
if (!pitchLine.pitchDataMap.has(key)) {
stage.removeChild(lineStrip.displayObject);
lineStripsContainer.removeChild(lineStrip.displayObject);
removedLineStrips.push(lineStrip);
pitchLine.lineStripMap.delete(key);
}
Expand All @@ -171,7 +173,7 @@ const updateLineStrips = (pitchLine: PitchLine) => {
const currentLineStrip = pitchLine.lineStripMap.get(key)!;
// テーマなど色が変更された場合、LineStripを再作成する
if (!currentLineStrip.color.equals(pitchLine.color.value)) {
stage.removeChild(currentLineStrip.displayObject);
lineStripsContainer.removeChild(currentLineStrip.displayObject);
currentLineStrip.destroy();
pitchLine.lineStripMap.delete(key);
} else {
Expand Down Expand Up @@ -199,10 +201,10 @@ const updateLineStrips = (pitchLine: PitchLine) => {
}
// pitchEditLineの場合は最後に追加する(originalより前面に表示)
if (pitchLine === pitchEditLine) {
stage.addChild(lineStrip.displayObject);
lineStripsContainer.addChild(lineStrip.displayObject);
} else {
// originalLineは最初に追加する(EditLineの背面に表示)
stage.addChildAt(lineStrip.displayObject, 0);
lineStripsContainer.addChildAt(lineStrip.displayObject, 0);
}
pitchLine.lineStripMap.set(key, lineStrip);
}
Expand Down Expand Up @@ -248,16 +250,19 @@ const updateLineStrips = (pitchLine: PitchLine) => {
};
const updatePoints = (pitchKnots: PitchKnots) => {
if (stage == undefined) {
throw new Error("stage is undefined.");
if (pointsContainer == undefined) {
throw new Error("pointsContainer is undefined.");
}
const tpqn = store.state.tpqn;
const zoomX = store.state.sequencerZoomX;
const zoomY = store.state.sequencerZoomY;
const offsetX = props.offsetX;
const offsetY = props.offsetY;
if (pitchKnots.knotsData == undefined) {
if (
pitchKnots.knotsData == undefined ||
pitchKnots.knotsData.xArray.length === 0
) {
return;
}
Expand All @@ -272,7 +277,7 @@ const updatePoints = (pitchKnots: PitchKnots) => {
pitchKnots.radius,
8,
);
stage.addChild(pitchKnots.points.displayObject);
pointsContainer.addChild(pitchKnots.points.displayObject);
}
// ポイントを計算してlineStripに設定&更新
Expand All @@ -296,33 +301,33 @@ const render = () => {
throw new Error("stage is undefined.");
}
// シンガーが未設定の場合はピッチラインをすべて非表示にして終了
const singer = store.getters.SELECTED_TRACK.singer;
if (!singer) {
for (const lineStrip of originalPitchLine.lineStripMap.values()) {
lineStrip.renderable = false;
}
for (const lineStrip of pitchEditLine.lineStripMap.values()) {
lineStrip.renderable = false;
}
renderer.render(stage);
return;
if (singer) {
stage.renderable = true;
updateLineStrips(originalPitchLine);
updateLineStrips(pitchEditLine);
updateLineStrips(interpOriginalPitchLine);
updatePoints(interpOriginalPitchKnots);
} else {
// シンガーが未設定の場合はピッチラインをすべて非表示にして終了
stage.renderable = false;
}
// ピッチラインのLineStripを更新する
updateLineStrips(originalPitchLine);
updateLineStrips(pitchEditLine);
updateLineStrips(interpOriginalPitchLine);
updatePoints(interpOriginalPitchKnots);
renderer.render(stage);
};
const toPitchData = (framewiseData: number[], frameRate: number): PitchData => {
const toPitchData = (
startFrame: number,
framewiseData: number[],
frameRate: number,
): PitchData => {
const data = framewiseData;
const ticksArray: number[] = [];
for (let i = 0; i < data.length; i++) {
const ticks = secondToTick(i / frameRate, tempos.value, tpqn.value);
const ticks = secondToTick(
(startFrame + i) / frameRate,
tempos.value,
tpqn.value,
);
ticksArray.push(ticks);
}
return { ticksArray, data };
Expand All @@ -345,19 +350,14 @@ const splitPitchData = (pitchData: PitchData, delimiter: number) => {
return pitchDataArray;
};
const setPitchDataToPitchLine = async (
pitchData: PitchData,
const setPitchDataArrayToPitchLine = async (
pitchDataArray: PitchData[],
pitchLine: PitchLine,
) => {
const partialPitchDataArray = splitPitchData(
pitchData,
VALUE_INDICATING_NO_DATA,
).filter((value) => value.data.length >= 2);
pitchLine.pitchDataMap.clear();
for (const partialPitchData of partialPitchDataArray) {
const hash = await calculatePitchDataHash(partialPitchData);
pitchLine.pitchDataMap.set(hash, partialPitchData);
for (const pitchData of pitchDataArray) {
const hash = await calculatePitchDataHash(pitchData);
pitchLine.pitchDataMap.set(hash, pitchData);
}
};
Expand Down Expand Up @@ -412,7 +412,7 @@ const generateOriginalPitchData = () => {
}
}
}
return toPitchData(tempData, frameRate);
return tempData;
};
const generatePitchEditData = () => {
Expand Down Expand Up @@ -448,40 +448,11 @@ const generatePitchEditData = () => {
throw new ExhaustiveError(previewPitchEditType);
}
}
return toPitchData(tempData, frameRate);
};
const generateInterpOriginalPitchData = (
points: { x: number; y: number }[],
) => {
const frameRate = editFrameRate.value;
const xArray: number[] = [];
for (let i = 0; i < 400; i++) {
xArray.push(i);
}
const tempData = Interpolate.catmullRom(points, xArray).map((value) =>
noteNumberToFrequency(value),
);
return toPitchData(tempData, frameRate);
return tempData;
};
const setKnotsDataToPitchKnots = (points: { x: number; y: number }[]) => {
const frameRate = editFrameRate.value;
const ticksArray: number[] = [];
for (let i = 0; i < points.length; i++) {
const ticks = secondToTick(
points[i].x / frameRate,
tempos.value,
tpqn.value,
);
ticksArray.push(ticks);
}
interpOriginalPitchKnots.knotsData = {
xArray: ticksArray,
yArray: points.map((value) => value.y),
};
const setKnotsDataToPitchKnots = (knotsData: KnotsData) => {
interpOriginalPitchKnots.knotsData = knotsData;
};
const asyncLock = new AsyncLock({ maxPending: 1 });
Expand All @@ -492,23 +463,14 @@ watch(
asyncLock.acquire(
"originalPitch",
async () => {
const originalPitchData = generateOriginalPitchData();
await setPitchDataToPitchLine(originalPitchData, originalPitchLine);
const points = [
{ x: 100, y: 60 },
{ x: 160, y: 62 },
{ x: 165, y: 62 },
{ x: 180, y: 65 },
{ x: 220, y: 63 },
{ x: 290, y: 69 },
];
const interpOriginalPitchData = generateInterpOriginalPitchData(points);
await setPitchDataToPitchLine(
interpOriginalPitchData,
interpOriginalPitchLine,
);
setKnotsDataToPitchKnots(points);
const frameRate = editorFrameRate.value;
const framewiseData = generateOriginalPitchData();
const pitchData = toPitchData(0, framewiseData, frameRate);
const pitchDataArray = splitPitchData(
pitchData,
VALUE_INDICATING_NO_DATA,
).filter((value) => value.data.length >= 2);
await setPitchDataArrayToPitchLine(pitchDataArray, originalPitchLine);
renderInNextFrame = true;
},
Expand All @@ -528,8 +490,49 @@ watch(
asyncLock.acquire(
"pitchEdit",
async () => {
const pitchEditData = generatePitchEditData();
await setPitchDataToPitchLine(pitchEditData, pitchEditLine);
const frameRate = editorFrameRate.value;
const framewiseData = generatePitchEditData();
const pitchData = toPitchData(0, framewiseData, frameRate);
const pitchDataArray = splitPitchData(
pitchData,
VALUE_INDICATING_NO_DATA,
).filter((value) => value.data.length >= 2);
await setPitchDataArrayToPitchLine(pitchDataArray, pitchEditLine);
const interpPitchDataArray: PitchData[] = [];
const knotsData: KnotsData = { xArray: [], yArray: [] };
for (const pitchData of pitchDataArray) {
const points1: { x: number; y: number }[] = [];
for (let i = 0; i < pitchData.ticksArray.length; i++) {
const ticks = pitchData.ticksArray[i];
const freq = pitchData.data[i];
const noteNumber = frequencyToNoteNumber(freq);
points1.push({ x: ticks, y: noteNumber });
}
const points2 = iterativeEndPointFit(points1, 0.12);
knotsData.xArray.push(...points2.map((value) => value.x));
knotsData.yArray.push(...points2.map((value) => value.y));
const period = 10;
const minX = points2[0].x;
const maxX = getLast(points2).x;
const xValues: number[] = [];
for (let i = minX; i < maxX; i += period) {
xValues.push(i);
}
xValues.push(maxX);
const yValues = Interpolate.catmullRom(points2, xValues);
const interpPitchData: PitchData = {
ticksArray: xValues,
data: yValues.map((value) => noteNumberToFrequency(value)),
};
interpPitchDataArray.push(interpPitchData);
}
await setPitchDataArrayToPitchLine(
interpPitchDataArray,
interpOriginalPitchLine,
);
setKnotsDataToPitchKnots(knotsData);
renderInNextFrame = true;
},
(err) => {
Expand Down Expand Up @@ -593,6 +596,11 @@ onMountedOrActivated(() => {
autoDensity: true,
});
stage = new PIXI.Container();
lineStripsContainer = new PIXI.Container();
pointsContainer = new PIXI.Container();
stage.addChild(lineStripsContainer);
stage.addChild(pointsContainer);
// webGLVersionをチェックする
// 2未満の場合、ピッチの表示ができないのでエラーとしてロギングする
Expand Down
Loading

0 comments on commit 2e44280

Please sign in to comment.