Skip to content

Commit

Permalink
デフォルトプリセット周りのリファクタ (#1274)
Browse files Browse the repository at this point in the history
Co-authored-by: Hiroshiba <[email protected]>
  • Loading branch information
k-chop and Hiroshiba authored Apr 8, 2023
1 parent 876d519 commit c11f551
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 123 deletions.
5 changes: 1 addition & 4 deletions src/composables/useDefaultPreset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,14 @@ export const useDefaultPreset = () => {
const store = useStore();

const defaultPresetKeys = computed(() => store.state.defaultPresetKeys);
const defaultPresetKeySets = computed(
() => new Set(Object.values(store.state.defaultPresetKeys))
);

const getDefaultPresetKeyForVoice = (voice: Voice): string => {
const voiceId = VoiceId(voice);
return defaultPresetKeys.value[voiceId];
};

const isDefaultPresetKey = (presetKey: PresetKey): boolean => {
return defaultPresetKeySets.value.has(presetKey);
return store.getters.DEFAULT_PRESET_KEY_SETS.has(presetKey);
};

return {
Expand Down
168 changes: 56 additions & 112 deletions src/store/audio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
} from "./utility";
import { convertAudioQueryFromEditorToEngine } from "./proxy";
import { createPartialStore } from "./vuex";
import { determineNextPresetKey } from "./preset";
import {
AudioKey,
CharacterInfo,
Expand All @@ -31,12 +32,12 @@ import {
EngineId,
MoraDataType,
MorphingInfo,
Preset,
PresetKey,
SpeakerId,
StyleId,
StyleInfo,
Voice,
VoiceId,
WriteFileErrorResult,
} from "@/type/preload";
import { AudioQuery, AccentPhrase, Speaker, SpeakerInfo } from "@/openapi";
Expand Down Expand Up @@ -188,69 +189,30 @@ export function getCharacterInfo(
}

/**
* configを参照して割り当てるべきpresetKeyとそのPresetを適用すべきかどうかを返す
* 与えたAudioItemを元に、Presetを適用した新しいAudioItemを返す
*/
export function determineNextPresetKey(
state: State,
voice: Voice,
presetKeyCandidate: PresetKey | undefined,
shouldCopyBaseAudioItem: boolean,
isVoiceChanged = false
): {
nextPresetKey: PresetKey | undefined;
shouldApplyPreset: boolean;
} {
const defaultPresetKeyForCurrentVoice =
state.defaultPresetKeys[VoiceId(voice)];

const isDefaultPreset = Object.values(state.defaultPresetKeys).some(
(key) => key === presetKeyCandidate
);

// コピーすべきBaseAudioItemがない=初回作成時
if (!shouldCopyBaseAudioItem) {
return {
nextPresetKey: defaultPresetKeyForCurrentVoice,
shouldApplyPreset: state.experimentalSetting.enablePreset,
};
export function applyAudioPresetToAudioItem(
audioItem: AudioItem,
presetItem: Preset
): AudioItem {
if (audioItem.query == undefined) {
throw new Error("audioItem.query is undefined");
}

// ボイス切り替え時
if (isVoiceChanged) {
if (state.experimentalSetting.shouldApplyDefaultPresetOnVoiceChanged) {
// デフォルトプリセットを適用する
return {
nextPresetKey: defaultPresetKeyForCurrentVoice,
shouldApplyPreset: true,
};
}

// 引き継ぎ元が他スタイルのデフォルトプリセットだった場合
// 別キャラのデフォルトプリセットを引き継がないようにする
// それ以外は指定そのまま
return {
nextPresetKey: isDefaultPreset
? defaultPresetKeyForCurrentVoice
: presetKeyCandidate,
shouldApplyPreset: false,
};
}
// Filter name property from presetItem in order to extract audioInfos.
const { name: _, morphingInfo, ...presetAudioInfos } = presetItem;

// 以下はAudioItemコピー時
// Type Assertion
const audioInfos: Omit<
AudioQuery,
"accentPhrases" | "outputSamplingRate" | "outputStereo" | "kana"
> = presetAudioInfos;

if (state.inheritAudioInfo) {
// パラメータ引継ぎがONならそのまま引き継ぐ
return {
nextPresetKey: presetKeyCandidate,
shouldApplyPreset: false,
};
}
const newAudioItem = { ...audioItem };
newAudioItem.query = { ...audioItem.query, ...audioInfos };
newAudioItem.morphingInfo = morphingInfo ? { ...morphingInfo } : undefined;

// それ以外はデフォルトプリセットを割り当て、適用するかはプリセットのON/OFFに依存
return {
nextPresetKey: defaultPresetKeyForCurrentVoice,
shouldApplyPreset: state.experimentalSetting.enablePreset,
};
return newAudioItem;
}

const audioBlobCache: Record<string, Blob> = {};
Expand Down Expand Up @@ -603,9 +565,9 @@ export const audioStore = createPartialStore<AudioStoreTypes>({
}).catch(() => undefined)
: undefined;

const audioItem: AudioItem = { text, voice };
const newAudioItem: AudioItem = { text, voice };
if (query != undefined) {
audioItem.query = query;
newAudioItem.query = query;
}

const presetKeyCandidate = payload.baseAudioItem?.presetKey;
Expand All @@ -614,37 +576,45 @@ export const audioStore = createPartialStore<AudioStoreTypes>({
state,
voice,
presetKeyCandidate,
state.inheritAudioInfo && baseAudioItem !== undefined
baseAudioItem ? "copy" : "generate"
);
audioItem.presetKey = nextPresetKey;
newAudioItem.presetKey = nextPresetKey;

// audioItemに対してプリセットを適用する
if (shouldApplyPreset) {
if (nextPresetKey) {
const preset = state.presetItems[nextPresetKey];
return applyAudioPresetToAudioItem(newAudioItem, preset);
}
}

// プリセットを適用しないならパラメータを引き継ぐ
if (
state.inheritAudioInfo &&
baseAudioItem &&
baseAudioItem.query &&
audioItem.query
newAudioItem.query
) {
//引数にbaseAudioItemがある場合、話速等のパラメータを引き継いだAudioItemを返す
//baseAudioItem.queryが未設定の場合は引き継がない(起動直後等?)
audioItem.query.speedScale = baseAudioItem.query.speedScale;
audioItem.query.pitchScale = baseAudioItem.query.pitchScale;
audioItem.query.intonationScale = baseAudioItem.query.intonationScale;
audioItem.query.volumeScale = baseAudioItem.query.volumeScale;
audioItem.query.prePhonemeLength = baseAudioItem.query.prePhonemeLength;
audioItem.query.postPhonemeLength =
newAudioItem.query.speedScale = baseAudioItem.query.speedScale;
newAudioItem.query.pitchScale = baseAudioItem.query.pitchScale;
newAudioItem.query.intonationScale =
baseAudioItem.query.intonationScale;
newAudioItem.query.volumeScale = baseAudioItem.query.volumeScale;
newAudioItem.query.prePhonemeLength =
baseAudioItem.query.prePhonemeLength;
newAudioItem.query.postPhonemeLength =
baseAudioItem.query.postPhonemeLength;
audioItem.query.outputSamplingRate =
newAudioItem.query.outputSamplingRate =
baseAudioItem.query.outputSamplingRate;
audioItem.query.outputStereo = baseAudioItem.query.outputStereo;
audioItem.morphingInfo = baseAudioItem.morphingInfo;
}

// audioItemに対してプリセットを適用する
if (shouldApplyPreset) {
await dispatch("APPLY_AUDIO_PRESET_TO_AUDIO_ITEM", { audioItem });
newAudioItem.query.outputStereo = baseAudioItem.query.outputStereo;
newAudioItem.morphingInfo = baseAudioItem.morphingInfo
? { ...baseAudioItem.morphingInfo }
: undefined;
}

return audioItem;
return newAudioItem;
},
},

Expand Down Expand Up @@ -1045,41 +1015,16 @@ export const audioStore = createPartialStore<AudioStoreTypes>({
},
},

APPLY_AUDIO_PRESET_TO_AUDIO_ITEM: {
// FIXME: audioItemを直接書き換えないようにするか、関数化する
mutation(state, { audioItem }) {
if (
audioItem == undefined ||
audioItem.presetKey == undefined ||
audioItem.query == undefined
)
return;
const presetItem = state.presetItems[audioItem.presetKey];
if (presetItem == undefined) return;

// Filter name property from presetItem in order to extract audioInfos.
const { name: _, morphingInfo, ...presetAudioInfos } = presetItem;

// Type Assertion
const audioInfos: Omit<
AudioQuery,
"accentPhrases" | "outputSamplingRate" | "outputStereo" | "kana"
> = presetAudioInfos;
APPLY_AUDIO_PRESET: {
mutation(state, { audioKey }: { audioKey: AudioKey }) {
const audioItem = state.audioItems[audioKey];

audioItem.query = { ...audioItem.query, ...audioInfos };
if (!audioItem.presetKey) return;

audioItem.morphingInfo = morphingInfo;
},
action({ commit }, { audioItem }) {
commit("APPLY_AUDIO_PRESET_TO_AUDIO_ITEM", { audioItem });
},
},
const presetItem = state.presetItems[audioItem.presetKey];
const newAudioItem = applyAudioPresetToAudioItem(audioItem, presetItem);

APPLY_AUDIO_PRESET: {
mutation(state, { audioKey }: { audioKey: AudioKey }) {
audioStore.mutations.APPLY_AUDIO_PRESET_TO_AUDIO_ITEM(state, {
audioItem: state.audioItems[audioKey],
});
state.audioItems[audioKey] = newAudioItem;
},
},

Expand Down Expand Up @@ -2120,8 +2065,7 @@ export const audioCommandStore = transformCommandStore(
draft,
payload.voice,
presetKey,
true,
true
"changeVoice"
);

audioStore.mutations.SET_AUDIO_PRESET_KEY(draft, {
Expand Down
83 changes: 81 additions & 2 deletions src/store/preset.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,80 @@
import { v4 as uuidv4 } from "uuid";
import { createPartialStore } from "./vuex";
import { PresetStoreState, PresetStoreTypes } from "@/store/type";
import { Preset, PresetKey, VoiceId } from "@/type/preload";
import { PresetStoreState, PresetStoreTypes, State } from "@/store/type";
import { Preset, PresetKey, Voice, VoiceId } from "@/type/preload";

/**
* configを参照して割り当てるべきpresetKeyとそのPresetを適用すべきかどうかを返す
*
* generate: プロジェクト新規作成時、空のAudioItemを作成する場合
* copy: 元となるAudioItemがある場合(+ボタンで作成したとき)
* changeVoice: ボイス切り替え時
*/
export function determineNextPresetKey(
state: Pick<
State,
"defaultPresetKeys" | "experimentalSetting" | "inheritAudioInfo"
>,
voice: Voice,
presetKeyCandidate: PresetKey | undefined,
operation: "generate" | "copy" | "changeVoice"
): {
nextPresetKey: PresetKey | undefined;
shouldApplyPreset: boolean;
} {
const defaultPresetKeyForCurrentVoice =
state.defaultPresetKeys[VoiceId(voice)];

switch (operation) {
case "generate": {
// 初回作成時
return {
nextPresetKey: defaultPresetKeyForCurrentVoice,
shouldApplyPreset: state.experimentalSetting.enablePreset,
};
}
case "copy": {
// 元となるAudioItemがある場合
if (state.inheritAudioInfo) {
// パラメータ引継ぎがONならそのまま引き継ぐ
return {
nextPresetKey: presetKeyCandidate,
shouldApplyPreset: false,
};
}

// それ以外はデフォルトプリセットを割り当て、適用するかはプリセットのON/OFFに依存
return {
nextPresetKey: defaultPresetKeyForCurrentVoice,
shouldApplyPreset: state.experimentalSetting.enablePreset,
};
}
case "changeVoice": {
// ボイス切り替え時
if (state.experimentalSetting.shouldApplyDefaultPresetOnVoiceChanged) {
// デフォルトプリセットを適用する
return {
nextPresetKey: defaultPresetKeyForCurrentVoice,
shouldApplyPreset: true,
};
}

const isDefaultPreset = Object.values(state.defaultPresetKeys).some(
(key) => key === presetKeyCandidate
);

// 引き継ぎ元が他スタイルのデフォルトプリセットだった場合
// 別キャラのデフォルトプリセットを引き継がないようにする
// それ以外は指定そのまま
return {
nextPresetKey: isDefaultPreset
? defaultPresetKeyForCurrentVoice
: presetKeyCandidate,
shouldApplyPreset: false,
};
}
}
}

export const presetStoreState: PresetStoreState = {
presetItems: {},
Expand All @@ -10,6 +83,12 @@ export const presetStoreState: PresetStoreState = {
};

export const presetStore = createPartialStore<PresetStoreTypes>({
DEFAULT_PRESET_KEY_SETS: {
getter: (state) => {
return new Set(Object.values(state.defaultPresetKeys));
},
},

SET_PRESET_ITEMS: {
mutation(
state,
Expand Down
8 changes: 3 additions & 5 deletions src/store/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -359,11 +359,6 @@ export type AudioStoreTypes = {
};
};

APPLY_AUDIO_PRESET_TO_AUDIO_ITEM: {
mutation: { audioItem: AudioItem };
action(payload: { audioItem: AudioItem }): void;
};

APPLY_AUDIO_PRESET: {
mutation: { audioKey: AudioKey };
};
Expand Down Expand Up @@ -1263,6 +1258,9 @@ export type PresetStoreState = {
};

export type PresetStoreTypes = {
DEFAULT_PRESET_KEY_SETS: {
getter: Set<PresetKey>;
};
SET_PRESET_ITEMS: {
mutation: {
presetItems: Record<PresetKey, Preset>;
Expand Down

0 comments on commit c11f551

Please sign in to comment.