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

ENH: モーフィングUIの実装 #1030

Merged
merged 15 commits into from
Jan 16, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/components/AudioDetail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -504,8 +504,10 @@ export default defineComponent({
});
} catch (e) {
let msg: string | undefined;
if (e instanceof Error && e.message !== "") {
msg = e.message;
if (e instanceof Error && e.message === "VALID_MOPHING_ERROR") {
msg = "モーフィングの設定が無効です。";
} else {
window.electron.logError(e);
}
$q.dialog({
title: "再生に失敗しました",
Expand Down
15 changes: 8 additions & 7 deletions src/components/DictionaryManageDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -483,12 +483,14 @@ export default defineComponent({
audioItem,
});
if (!blob) {
const audioResult = await createUILockAction(
store.dispatch("GENERATE_AUDIO_FROM_AUDIO_ITEM", {
audioItem,
})
);
if (audioResult.result !== "SUCCESS") {
try {
blob = await createUILockAction(
store.dispatch("GENERATE_AUDIO_FROM_AUDIO_ITEM", {
audioItem,
})
);
} catch (e) {
window.electron.logError(e);
nowGenerating.value = false;
$q.dialog({
title: "生成に失敗しました",
Expand All @@ -501,7 +503,6 @@ export default defineComponent({
});
return;
}
blob = audioResult.blob;
}
nowGenerating.value = false;
nowPlaying.value = true;
Expand Down
140 changes: 68 additions & 72 deletions src/store/audio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
AudioStoreTypes,
AudioCommandStoreTypes,
transformCommandStore,
GenerateAudioResultObject,
} from "./type";
import { createUILockAction, withProgress } from "./ui";
import {
Expand Down Expand Up @@ -1079,71 +1078,56 @@ export const audioStore = createPartialStore<AudioStoreTypes>({
async (
{ dispatch, getters, state },
{ audioItem }: { audioItem: AudioItem }
): Promise<GenerateAudioResultObject> => {
) => {
const engineId = audioItem.engineId;
if (engineId === undefined) {
window.electron.logError("engineId is not defined for audioItem");
return {
result: "EDITOR_ERROR",
};
}
if (engineId === undefined)
throw new Error("engineId is not defined for audioItem");

const [id, audioQuery] = await generateUniqueIdAndQuery(
state,
audioItem
);
if (audioQuery == undefined)
throw new Error("audioQuery is not defined for audioItem");

const speaker = audioItem.styleId;
if (audioQuery == undefined || speaker == undefined) {
window.electron.logError(
"audioQuery == undefined || speaker == undefined"
);
return {
result: "EDITOR_ERROR",
};
}
if (speaker == undefined)
throw new Error("speaker is not defined for audioItem");

const engineAudioQuery = convertAudioQueryFromEditorToEngine(
audioQuery,
state.engineManifests[engineId].defaultSamplingRate
);

return dispatch("INSTANTIATE_ENGINE_CONNECTOR", {
engineId,
})
.then(async (instance): Promise<GenerateAudioResultObject> => {
let blob: Blob;
if (
audioItem.morphingInfo != undefined &&
state.experimentalSetting.enableMorphing
) {
if (!getters.VALID_MOPHING_INFO(audioItem)) {
return {
result: "VALID_MOPHING_ERROR",
errorMessage: "モーフィングの設定が無効です。",
};
}
blob = await instance.invoke(
"synthesisMorphingSynthesisMorphingPost"
)({
audioQuery: engineAudioQuery,
baseSpeaker: speaker,
targetSpeaker: audioItem.morphingInfo.targetStyleId,
morphRate: audioItem.morphingInfo.rate,
});
} else {
blob = await instance.invoke("synthesisSynthesisPost")({
audioQuery: engineAudioQuery,
speaker,
enableInterrogativeUpspeak:
state.experimentalSetting.enableInterrogativeUpspeak,
});
}
audioBlobCache[id] = blob;
return { result: "SUCCESS", blob };
})
.catch((e) => {
window.electron.logError(e);
return { result: "ENGINE_ERROR" };
});
}).then(async (instance) => {
let blob: Blob;
if (
audioItem.morphingInfo != undefined &&
state.experimentalSetting.enableMorphing
) {
if (!getters.VALID_MOPHING_INFO(audioItem))
throw new Error("VALID_MOPHING_ERROR");
blob = await instance.invoke(
"synthesisMorphingSynthesisMorphingPost"
)({
audioQuery: engineAudioQuery,
baseSpeaker: speaker,
targetSpeaker: audioItem.morphingInfo.targetStyleId,
morphRate: audioItem.morphingInfo.rate,
});
} else {
blob = await instance.invoke("synthesisSynthesisPost")({
audioQuery: engineAudioQuery,
speaker,
enableInterrogativeUpspeak:
state.experimentalSetting.enableInterrogativeUpspeak,
});
}
audioBlobCache[id] = blob;
return blob;
});
}
),
},
Expand Down Expand Up @@ -1218,15 +1202,21 @@ export const audioStore = createPartialStore<AudioStoreTypes>({

let blob = await dispatch("GET_AUDIO_CACHE", { audioKey });
if (!blob) {
const audioResult = await dispatch("GENERATE_AUDIO", { audioKey });
if (audioResult.result !== "SUCCESS") {
try {
blob = await dispatch("GENERATE_AUDIO", { audioKey });
} catch (e) {
let errorMessage = undefined;
if (e instanceof Error && e.message === "VALID_MOPHING_ERROR") {
errorMessage = "モーフィングの設定が無効です。";
Hiroshiba marked this conversation as resolved.
Show resolved Hide resolved
} else {
window.electron.logError(e);
}
return {
result: "ENGINE_ERROR",
path: filePath,
errorMessage: audioResult.errorMessage,
errorMessage,
};
}
blob = audioResult.blob;
}

let writeFileResult = await window.electron.writeFile({
Expand Down Expand Up @@ -1420,16 +1410,23 @@ export const audioStore = createPartialStore<AudioStoreTypes>({
for (const audioKey of state.audioKeys) {
let blob = await dispatch("GET_AUDIO_CACHE", { audioKey });
if (!blob) {
const audioResult = await dispatch("GENERATE_AUDIO", { audioKey });
callback?.(++finishedCount, totalCount);
if (audioResult.result !== "SUCCESS") {
try {
blob = await dispatch("GENERATE_AUDIO", { audioKey });
} catch (e) {
let errorMessage = undefined;
if (e instanceof Error && e.message === "VALID_MOPHING_ERROR") {
errorMessage = "モーフィングの設定が無効です。";
Hiroshiba marked this conversation as resolved.
Show resolved Hide resolved
} else {
window.electron.logError(e);
}
return {
result: "ENGINE_ERROR",
path: filePath,
errorMessage: audioResult.errorMessage,
errorMessage,
};
} finally {
callback?.(++finishedCount, totalCount);
}
blob = audioResult.blob;
}
const encodedBlob = await base64Encoder(blob);
if (encodedBlob === undefined) {
Expand Down Expand Up @@ -1631,18 +1628,17 @@ export const audioStore = createPartialStore<AudioStoreTypes>({
audioKey,
nowGenerating: true,
});
const audioResult = await withProgress(
dispatch("GENERATE_AUDIO", { audioKey }),
dispatch
);
commit("SET_AUDIO_NOW_GENERATING", {
audioKey,
nowGenerating: false,
});
if (audioResult.result !== "SUCCESS") {
throw new Error(audioResult.errorMessage);
try {
blob = await withProgress(
dispatch("GENERATE_AUDIO", { audioKey }),
dispatch
);
} finally {
commit("SET_AUDIO_NOW_GENERATING", {
audioKey,
nowGenerating: false,
});
}
blob = audioResult.blob;
}

return dispatch("PLAY_AUDIO_BLOB", {
Expand Down
14 changes: 2 additions & 12 deletions src/store/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,6 @@ export type Command = {
redoPatches: Patch[];
};

export type GenerateAudioResultObject =
| {
result: "SUCCESS";
blob: Blob;
}
| {
result: "VALID_MOPHING_ERROR" | "EDITOR_ERROR" | "ENGINE_ERROR";
errorMessage?: string;
};

export type EngineState = "STARTING" | "FAILED_STARTING" | "ERROR" | "READY";
export type SaveResult =
| "SUCCESS"
Expand Down Expand Up @@ -370,11 +360,11 @@ export type AudioStoreTypes = {
};

GENERATE_AUDIO: {
action(payload: { audioKey: string }): Promise<GenerateAudioResultObject>;
action(payload: { audioKey: string }): Promise<Blob>;
};

GENERATE_AUDIO_FROM_AUDIO_ITEM: {
action(payload: { audioItem: AudioItem }): GenerateAudioResultObject;
action(payload: { audioItem: AudioItem }): Blob;
};

CONNECT_AUDIO: {
Expand Down