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

[song]ノーツが先頭に存在すると動作しない #2031

Closed
1 of 3 tasks
tsym77yoshi opened this issue Apr 27, 2024 · 2 comments · Fixed by #2032
Closed
1 of 3 tasks

[song]ノーツが先頭に存在すると動作しない #2031

tsym77yoshi opened this issue Apr 27, 2024 · 2 comments · Fixed by #2032
Assignees

Comments

@tsym77yoshi
Copy link
Contributor

不具合の内容

ノーツが先頭に存在するとエラーになる

現象・ログ

ノーツが1小節目の最初に存在するとエラーになる(メッセージは歌詞が一文字までですとなっているが原因は違いそうです)
image

再現手順

一番最初にノーツを置くとでます。後ろの場所に移動させたらエラーは消えました。

VOICEVOXのバージョン

0.19.0

OSの種類/ディストリ/バージョン

  • Windows
  • macOS
  • Linux

その他

apiで最初に無音の秒数がないと実行できない仕様に関係するバグだと思います

@KoharuYuzuki
Copy link
Contributor

Mac版でも同様のバグを確認しました。
一番最初にノーツを置くと、applyPitchEdit関数のstartFrameがマイナス値になり、f0[i - startFrame]にundefinedを格納してしまいます。
そうすると、フレームごとの音量を得る際にバリデーションエラーが発生します。
正しい修正方法か分かりませんが、マイナス値を0にしたところ動作するようになりました。

voicevox/src/sing/domain.ts

Lines 424 to 457 in fb0adce

export function applyPitchEdit(
singingGuide: SingingGuide,
pitchEditData: number[],
editFrameRate: number,
) {
// 歌い方のフレームレートと編集フレームレートが一致しない場合はエラー
// TODO: 補間するようにする
if (singingGuide.frameRate !== editFrameRate) {
throw new Error(
"The frame rate between the singing guide and the edit data does not match.",
);
}
const unvoicedPhonemes = UNVOICED_PHONEMES;
const f0 = singingGuide.query.f0;
const phonemes = singingGuide.query.phonemes;
// 各フレームの音素の配列を生成する
const framePhonemes = convertToFramePhonemes(phonemes);
if (f0.length !== framePhonemes.length) {
throw new Error("f0.length and framePhonemes.length do not match.");
}
const startFrame = Math.round(
singingGuide.startTime * singingGuide.frameRate,
);
const endFrame = Math.min(startFrame + f0.length, pitchEditData.length);
for (let i = startFrame; i < endFrame; i++) {
const phoneme = framePhonemes[i - startFrame];
const voiced = !unvoicedPhonemes.includes(phoneme);
if (voiced && pitchEditData[i] !== VALUE_INDICATING_NO_DATA) {
f0[i - startFrame] = pitchEditData[i];
}
}
}

@sigprogramming
Copy link
Contributor

ご報告&調査ありがとうございます!

こちら、以下を考慮せずpitchEditDataをf0に転写しようとして、f0にundefinedが入ってしまっているようです。

  • 最初のノートの開始が1秒未満の場合、f0の開始がマイナスフレームになる
  • pitchEditDataは0フレームから開始

修正方法ですが、startFrameの算出部分を

const f0StartFrame = Math.round(
  singingGuide.startTime * singingGuide.frameRate,
);
const startFrame = Math.max(0, f0StartFrame);

に変更するとf0にundefinedが入らなくなり、エラーも発生しなくなると思います。

修正PRを作成します…!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants