diff --git a/src/sing/domain.ts b/src/sing/domain.ts index 4d0f9bf54f..62a4b9b9d5 100644 --- a/src/sing/domain.ts +++ b/src/sing/domain.ts @@ -505,8 +505,8 @@ type PhonemeTiming = { }; export type PhonemeTimingEdit = { - phonemeIndex: number; // ノート内での音素の順番 - offset: number; // 単位は秒 + phonemeIndexInNote: number; + offsetSeconds: number; }; export type PhonemeTimingEditData = Map; @@ -667,7 +667,7 @@ function applyPhonemeTimingEditToPhonemeTimings( phonemeTimingEditData: PhonemeTimingEditData, frameRate: number, ) { - let phonemeIndex = 0; + let phonemeIndexInNote = 0; for (let i = 0; i < phonemeTimings.length; i++) { const phonemeTiming = phonemeTimings[i]; const prevPhonemeTiming = getPrev(phonemeTimings, i); @@ -677,9 +677,9 @@ function applyPhonemeTimingEditToPhonemeTimings( prevPhonemeTiming == undefined || phonemeTiming.noteId !== prevPhonemeTiming.noteId ) { - phonemeIndex = 0; + phonemeIndexInNote = 0; } else { - phonemeIndex++; + phonemeIndexInNote++; } if (phonemeTiming.phoneme === "pau") { @@ -693,8 +693,11 @@ function applyPhonemeTimingEditToPhonemeTimings( continue; } for (const phonemeTimingEdit of phonemeTimingEdits) { - if (phonemeTimingEdit.phonemeIndex === phonemeIndex) { - const offsetFrame = secondToFrame(phonemeTimingEdit.offset, frameRate); + if (phonemeTimingEdit.phonemeIndexInNote === phonemeIndexInNote) { + const offsetFrame = secondToFrame( + phonemeTimingEdit.offsetSeconds, + frameRate, + ); const roundedOffsetFrame = Math.round(offsetFrame); phonemeTiming.startFrame += roundedOffsetFrame; @@ -702,11 +705,14 @@ function applyPhonemeTimingEditToPhonemeTimings( prevPhonemeTiming.endFrame = phonemeTiming.startFrame; } } else if ( - phonemeTimingEdit.phonemeIndex === phonemeIndex + 1 && + phonemeTimingEdit.phonemeIndexInNote === phonemeIndexInNote + 1 && nextPhonemeTiming?.phoneme === "pau" ) { // NOTE: 休符のpauseは休符の直前のノートに含まれる音素として扱う - const offsetFrame = secondToFrame(phonemeTimingEdit.offset, frameRate); + const offsetFrame = secondToFrame( + phonemeTimingEdit.offsetSeconds, + frameRate, + ); const roundedOffsetFrame = Math.round(offsetFrame); phonemeTiming.endFrame += roundedOffsetFrame; diff --git a/tests/unit/domain/sing/applyPhonemeTimingEdit.spec.ts b/tests/unit/domain/sing/applyPhonemeTimingEdit.spec.ts index 5ce7ea1677..932a948eb4 100644 --- a/tests/unit/domain/sing/applyPhonemeTimingEdit.spec.ts +++ b/tests/unit/domain/sing/applyPhonemeTimingEdit.spec.ts @@ -126,8 +126,8 @@ describe("applyPhonemeTimingEditAndAdjust", () => { it("音素タイミング編集が適用される", () => { const phonemeTimingEditData = new Map([ - [noteIds[1], [{ phonemeIndex: 0, offset: -3 / frameRate }]], - [noteIds[4], [{ phonemeIndex: 1, offset: 6 / frameRate }]], + [noteIds[1], [{ phonemeIndexInNote: 0, offsetSeconds: -3 / frameRate }]], + [noteIds[4], [{ phonemeIndexInNote: 1, offsetSeconds: 6 / frameRate }]], ]); const expectedPhraseQueries = structuredClone(phraseQueries); expectedPhraseQueries[0].phonemes[2].frameLength -= 3; @@ -146,8 +146,8 @@ describe("applyPhonemeTimingEditAndAdjust", () => { it("音素が重ならないように音素タイミングが調整される", () => { const phonemeTimingEditData = new Map([ - [noteIds[1], [{ phonemeIndex: 1, offset: -12 / frameRate }]], - [noteIds[2], [{ phonemeIndex: 2, offset: 60 / frameRate }]], + [noteIds[1], [{ phonemeIndexInNote: 1, offsetSeconds: -12 / frameRate }]], + [noteIds[2], [{ phonemeIndexInNote: 2, offsetSeconds: 60 / frameRate }]], ]); const expectedPhraseQueries = structuredClone(phraseQueries); expectedPhraseQueries[0].phonemes[2].frameLength -= 6; @@ -167,8 +167,8 @@ describe("applyPhonemeTimingEditAndAdjust", () => { it("pauseのフレーム長が1以上になるように音素タイミングが調整される", () => { const phonemeTimingEditData = new Map([ - [noteIds[3], [{ phonemeIndex: 1, offset: -60 / frameRate }]], - [noteIds[5], [{ phonemeIndex: 2, offset: 60 / frameRate }]], + [noteIds[3], [{ phonemeIndexInNote: 1, offsetSeconds: -60 / frameRate }]], + [noteIds[5], [{ phonemeIndexInNote: 2, offsetSeconds: 60 / frameRate }]], ]); const expectedPhraseQueries = structuredClone(phraseQueries); expectedPhraseQueries[1].phonemes[0].frameLength -= 39;