Skip to content

Commit

Permalink
既存キャラクターの音域調整量をマジックナンバーとして埋め込み、自動入力する (#2028)
Browse files Browse the repository at this point in the history
* 音量域→声量

* 音域自動調整ワークアラウンド 実装しないほうが良いかもなやつ

* stash

* withRelated追加

* 音域の値追加

* 説明追加

* 説明を追加

* COMMAND_SET_SINGERが冗長だった

* だいぶ見づらいので修正
  • Loading branch information
Hiroshiba authored Apr 26, 2024
1 parent 3d84439 commit fb0adce
Show file tree
Hide file tree
Showing 7 changed files with 266 additions and 17 deletions.
21 changes: 18 additions & 3 deletions public/howtouse.md
Original file line number Diff line number Diff line change
Expand Up @@ -301,10 +301,18 @@ VOICEVOX では、歌声合成機能がプロトタイプ版として提供さ

### 音域調整

デフォルトの設定だと、声が低いキャラクターがうまく歌えないことがあります
そのような場合は「音域調整」を`-12``-24`などにすることで、音域を低めに合わせることができます
「音域調整」の値が大きいほど高い音域で、小さいほど低い音域でうまく歌えるようになります
デフォルトではキャラクターに合う音域が設定されています

将来的にこの値は自動設定される予定です。
「音域調整」の値と中央のキーの関係はおおよそ以下の通りです。

| 音域調整の値 | 中央のキー |
| --- | --- |
| 0 | G4(ソ4) |
| -7 | C4(ド4) |
| -12 | G3(ソ3) |
| -19 | C3(ド3) |
| -24 | G2(ソ2) |

### 声量調整

Expand All @@ -313,11 +321,18 @@ VOICEVOX では、歌声合成機能がプロトタイプ版として提供さ

将来的にこの値は自動設定される予定です。

### ピッチ編集

「設定」の「実験的機能」から「ソング:ピッチ編集機能」をONにすることで、歌の音程を細かく制御することができます。

### ソング機能のよくある質問

Q. 赤くなって声が再生されない
A. なにかしらのエラー状態を示しています。現在のバージョンでは、1つのノート(音符)につき日本語1文字分のみ入力できます。またノートが重なっていてもエラーとなります。

Q. 思った高さの音が出ない
A. 音域がずれている可能性があります。「音域調整」で調整してみてください。

## オプション

「設定」の「オプション」でいろいろな設定を変更することができます。
Expand Down
5 changes: 4 additions & 1 deletion src/components/Sing/CharacterMenuButton/MenuButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,10 @@ const changeStyleId = (speakerUuid: SpeakerId, styleId: StyleId) => {
`No engineId for target character style (speakerUuid == ${speakerUuid}, styleId == ${styleId})`,
);
store.dispatch("COMMAND_SET_SINGER", { singer: { engineId, styleId } });
store.dispatch("COMMAND_SET_SINGER", {
singer: { engineId, styleId },
withRelated: true,
});
};
const getDefaultStyle = (speakerUuid: string) => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/Sing/SingEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ onetimeWatch(
// CI上のe2eテストのNemoエンジンには歌手がいないためエラーになるのでワークアラウンド
// FIXME: 歌手をいると見せかけるmock APIを作り、ここのtry catchを削除する
try {
await store.dispatch("SET_SINGER", {});
await store.dispatch("SET_SINGER", { withRelated: true });
} catch (e) {
window.backend.logError(e);
}
Expand Down
215 changes: 215 additions & 0 deletions src/sing/workaroundKeyRangeAdjustment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
/**
* 音域調整量の自動入力のためのワークアラウンド。
* 本来エンジンから得るべき音域調整量を、マジックナンバーとして直接データ化している。
*
* FIXME: スタイルの音域をエンジンから取得可能にし、音域調整量を計算するように修正する。
*/

import { createLogger } from "@/domain/frontend/log";
import { Singer } from "@/store/type";
import { CharacterInfo, EngineId } from "@/type/preload";

const logger = createLogger("sing/workaroundKeyRangeAdjustment");

const workaroundKeyRangeAdjustmentValues: {
[key: string]: { [key: string]: number };
} = {
四国めたん: {
ノーマル: -4,
あまあま: -4,
ツンツン: -5,
セクシー: -4,
ヒソヒソ: -9,
},
ずんだもん: {
ノーマル: -2,
あまあま: 0,
ツンツン: -3,
セクシー: 0,
ヒソヒソ: -7,
ヘロヘロ: -3,
なみだめ: 6,
},
春日部つむぎ: {
ノーマル: -2,
},
雨晴はう: {
ノーマル: 0,
},
波音リツ: {
ノーマル: -8,
クイーン: -5,
},
玄野武宏: {
ノーマル: -17,
喜び: -9,
ツンギレ: -14,
悲しみ: -18,
},
白上虎太郎: {
ふつう: -14,
わーい: -8,
びくびく: -7,
おこ: -9,
びえーん: -3,
},
青山龍星: {
ノーマル: -22,
熱血: -18,
不機嫌: -23,
喜び: -21,
しっとり: -27,
かなしみ: -22,
},
冥鳴ひまり: {
ノーマル: -7,
},
九州そら: {
ノーマル: -7,
あまあま: -2,
ツンツン: -6,
セクシー: -4,
},
もち子さん: {
ノーマル: -5,
"セクシー/あん子": -7,
泣き: -2,
怒り: -3,
喜び: -2,
のんびり: -5,
},
剣崎雌雄: {
ノーマル: -18,
},
WhiteCUL: {
ノーマル: -6,
たのしい: -3,
かなしい: -7,
びえーん: 0,
},
後鬼: {
"人間ver.": -7,
"ぬいぐるみver.": -2,
},
"No.7": {
ノーマル: -8,
アナウンス: -10,
読み聞かせ: -9,
},
ちび式じい: {
ノーマル: -18,
},
櫻歌ミコ: {
ノーマル: -6,
第二形態: -12,
ロリ: -7,
},
"小夜/SAYO": {
ノーマル: -4,
},
ナースロボ_タイプT: {
ノーマル: -6,
楽々: -3,
恐怖: -4,
},
"†聖騎士 紅桜†": {
ノーマル: -15,
},
雀松朱司: {
ノーマル: -21,
},
麒ヶ島宗麟: {
ノーマル: -17,
},
春歌ナナ: {
ノーマル: -2,
},
猫使アル: {
ノーマル: -8,
おちつき: -9,
うきうき: -7,
},
猫使ビィ: {
ノーマル: -1,
おちつき: -3,
},
中国うさぎ: {
ノーマル: -8,
おどろき: -4,
こわがり: -2,
へろへろ: -4,
},
栗田まろん: {
ノーマル: -14,
},
あいえるたん: {
ノーマル: -2,
},
満別花丸: {
ノーマル: -4,
元気: 2,
ささやき: -33,
ぶりっ子: 0,
ボーイ: -10,
},
琴詠ニア: {
ノーマル: -4,
},
};

/**
* 指定した歌手の音域調整量を取得するワークアラウンド。
* ハミングの場合はマジックナンバーを使う。
* 歌手の場合は0を返す。
*/
export function getWorkaroundKeyRangeAdjustment(
engineCharacterInfos: Record<EngineId, CharacterInfo[]>,
singer: Singer,
): number {
const defaultKeyRangeAdjustment = 0;

const characterInfos = engineCharacterInfos[singer.engineId];
if (characterInfos == undefined) {
logger.warn("characterInfos not found.", singer);
return defaultKeyRangeAdjustment;
}

const characterInfo = characterInfos.find((c) =>
c.metas.styles.find((s) => s.styleId === singer.styleId),
);
if (characterInfo == undefined) {
logger.warn("characterInfo not found.", singer);
return defaultKeyRangeAdjustment;
}

const styleInfo = characterInfo.metas.styles.find(
(s) => s.styleId === singer.styleId,
);
if (styleInfo == undefined) {
logger.warn("styleInfo not found.", singer);
return defaultKeyRangeAdjustment;
}

if (styleInfo.styleType == "frame_decode") {
// ハミングの場合はマジックナンバーを使う
const singerName = characterInfo.metas.speakerName;
const styleName = styleInfo.styleName;
if (styleName == undefined) {
logger.warn("styleName not found.", singer);
return defaultKeyRangeAdjustment;
}

const keyRangeAdjustment =
workaroundKeyRangeAdjustmentValues[singerName]?.[styleName];
if (keyRangeAdjustment == undefined) {
// 新しいキャラなどの場合はここに来る
logger.warn("keyRangeAdjustment not found.", singer);
return defaultKeyRangeAdjustment;
}

return keyRangeAdjustment;
} else {
// 歌手の場合はそのまま
return 0;
}
}
2 changes: 1 addition & 1 deletion src/store/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ export const projectStore = createPartialStore<ProjectStoreTypes>({
notes: tracks[0].notes,
},
});
await context.dispatch("SET_SINGER", {});
await context.dispatch("SET_SINGER", { withRelated: true });
await context.dispatch("CLEAR_PITCH_EDIT_DATA");

context.commit("SET_PROJECT_FILEPATH", { filePath: undefined });
Expand Down
30 changes: 23 additions & 7 deletions src/store/singing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ import {
createPromiseThatResolvesWhen,
round,
} from "@/sing/utility";
import { getWorkaroundKeyRangeAdjustment } from "@/sing/workaroundKeyRangeAdjustment";
import { createLogger } from "@/domain/frontend/log";
import { noteSchema } from "@/domain/project/schema";

Expand Down Expand Up @@ -218,12 +219,27 @@ export const singingStore = createPartialStore<SingingStoreTypes>({
},

SET_SINGER: {
mutation(state, { singer }: { singer?: Singer }) {
// 歌手をセットする。
// withRelatedがtrueの場合、関連する情報もセットする。
mutation(
state,
{ singer, withRelated }: { singer?: Singer; withRelated?: boolean },
) {
state.tracks[selectedTrackIndex].singer = singer;

if (withRelated == true && singer != undefined) {
// 音域調整量マジックナンバーを設定するワークアラウンド
const keyRangeAdjustment = getWorkaroundKeyRangeAdjustment(
state.characterInfos,
singer,
);
state.tracks[selectedTrackIndex].keyRangeAdjustment =
keyRangeAdjustment;
}
},
async action(
{ state, getters, dispatch, commit },
{ singer }: { singer?: Singer },
{ singer, withRelated }: { singer?: Singer; withRelated?: boolean },
) {
if (state.defaultStyleIds == undefined)
throw new Error("state.defaultStyleIds == undefined");
Expand All @@ -242,7 +258,7 @@ export const singingStore = createPartialStore<SingingStoreTypes>({
const styleId = singer?.styleId ?? defaultStyleId;

dispatch("SETUP_SINGER", { singer: { engineId, styleId } });
commit("SET_SINGER", { singer: { engineId, styleId } });
commit("SET_SINGER", { singer: { engineId, styleId }, withRelated });

dispatch("RENDER");
},
Expand Down Expand Up @@ -2529,12 +2545,12 @@ export const singingCommandStoreState: SingingCommandStoreState = {};
export const singingCommandStore = transformCommandStore(
createPartialStore<SingingCommandStoreTypes>({
COMMAND_SET_SINGER: {
mutation(draft, { singer }) {
singingStore.mutations.SET_SINGER(draft, { singer });
mutation(draft, { singer, withRelated }) {
singingStore.mutations.SET_SINGER(draft, { singer, withRelated });
},
async action({ dispatch, commit }, { singer }) {
async action({ dispatch, commit }, { singer, withRelated }) {
dispatch("SETUP_SINGER", { singer });
commit("COMMAND_SET_SINGER", { singer });
commit("COMMAND_SET_SINGER", { singer, withRelated });

dispatch("RENDER");
},
Expand Down
8 changes: 4 additions & 4 deletions src/store/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -840,8 +840,8 @@ export type SingingStoreTypes = {
};

SET_SINGER: {
mutation: { singer?: Singer };
action(payload: { singer?: Singer }): void;
mutation: { singer?: Singer; withRelated?: boolean };
action(payload: { singer?: Singer; withRelated?: boolean }): void;
};

SET_KEY_RANGE_ADJUSTMENT: {
Expand Down Expand Up @@ -1116,8 +1116,8 @@ export type SingingCommandStoreState = {

export type SingingCommandStoreTypes = {
COMMAND_SET_SINGER: {
mutation: { singer: Singer };
action(payload: { singer: Singer }): void;
mutation: { singer: Singer; withRelated?: boolean };
action(payload: { singer: Singer; withRelated?: boolean }): void;
};

COMMAND_SET_KEY_RANGE_ADJUSTMENT: {
Expand Down

0 comments on commit fb0adce

Please sign in to comment.