From 3d89f4f625147476480a2ad8dc682c915505f346 Mon Sep 17 00:00:00 2001 From: Nanashi Date: Fri, 15 Dec 2023 00:42:13 +0900 Subject: [PATCH] =?UTF-8?q?=E8=A4=87=E6=95=B0=E9=81=B8=E6=8A=9E=EF=BC=9A?= =?UTF-8?q?=E8=A9=B1=E8=80=85=E5=A4=89=E6=9B=B4=E3=81=99=E3=82=8B=E3=81=A8?= =?UTF-8?q?AudioQuery=E3=81=AE=E3=83=86=E3=82=AD=E3=82=B9=E3=83=88?= =?UTF-8?q?=E3=81=8CAudioCell=E3=81=AE=E3=83=86=E3=82=AD=E3=82=B9=E3=83=88?= =?UTF-8?q?=E3=81=A8=E4=B8=80=E8=87=B4=E3=81=97=E3=81=AA=E3=81=8F=E3=81=AA?= =?UTF-8?q?=E3=82=8B=E3=83=90=E3=82=B0=E3=82=92=E4=BF=AE=E6=AD=A3=20(#1665?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/audio.ts | 171 +++++++++++++++++++++++++-------------------- src/store/type.ts | 28 +++++--- 2 files changed, 114 insertions(+), 85 deletions(-) diff --git a/src/store/audio.ts b/src/store/audio.ts index 99a5ca9364..2af0fb0eaa 100644 --- a/src/store/audio.ts +++ b/src/store/audio.ts @@ -2011,57 +2011,60 @@ export const audioCommandStore = transformCommandStore( COMMAND_MULTI_CHANGE_VOICE: { mutation( - draft, - payload: { audioKeys: AudioKey[]; voice: Voice } & ( - | { update: "RollbackStyleId" } - | { - update: "AccentPhrases"; - accentPhrases: AccentPhrase[]; - } - | { - update: "AudioQuery"; - query: AudioQuery; - } - ) - ) { - for (const audioKey of payload.audioKeys) { - audioStore.mutations.SET_AUDIO_VOICE(draft, { - audioKey, - voice: payload.voice, - }); + state, + payload: { + voice: Voice; + changes: Record< + AudioKey, + | { + update: "AccentPhrases"; + accentPhrases: AccentPhrase[]; + } + | { + update: "AudioQuery"; + query: AudioQuery; + } + | { + update: "OnlyVoice"; + } + >; } + ) { + for (const [audioKey_, change] of Object.entries(payload.changes)) { + // TypeScriptは`Object.entries`のKeyの型を`string`としてしまうので、`as`で型を指定する + const audioKey = audioKey_ as AudioKey; - if (payload.update === "RollbackStyleId") return; - - for (const audioKey of payload.audioKeys) { - const presetKey = draft.audioItems[audioKey].presetKey; + const presetKey = state.audioItems[audioKey].presetKey; const { nextPresetKey, shouldApplyPreset } = determineNextPresetKey( - draft, + state, payload.voice, presetKey, "changeVoice" ); - audioStore.mutations.SET_AUDIO_PRESET_KEY(draft, { + audioStore.mutations.SET_AUDIO_PRESET_KEY(state, { audioKey, presetKey: nextPresetKey, }); - if (payload.update == "AccentPhrases") { - audioStore.mutations.SET_ACCENT_PHRASES(draft, { + audioStore.mutations.SET_AUDIO_VOICE(state, { + audioKey, + voice: payload.voice, + }); + if (change.update == "AccentPhrases") { + audioStore.mutations.SET_ACCENT_PHRASES(state, { audioKey, - accentPhrases: payload.accentPhrases, + accentPhrases: change.accentPhrases, }); - } else if (payload.update == "AudioQuery") { - audioStore.mutations.SET_AUDIO_QUERY(draft, { + } else if (change.update == "AudioQuery") { + audioStore.mutations.SET_AUDIO_QUERY(state, { audioKey, - audioQuery: payload.query, + audioQuery: change.query, }); } - if (shouldApplyPreset) { - audioStore.mutations.APPLY_AUDIO_PRESET(draft, { + audioStore.mutations.APPLY_AUDIO_PRESET(state, { audioKey, }); } @@ -2074,50 +2077,70 @@ export const audioCommandStore = transformCommandStore( const engineId = voice.engineId; const styleId = voice.styleId; await dispatch("SETUP_SPEAKER", { audioKeys, engineId, styleId }); - await Promise.all( - audioKeys.map(async (audioKey) => { - try { - const query = state.audioItems[audioKey].query; - if (query != undefined) { - const accentPhrases = query.accentPhrases; - const newAccentPhrases: AccentPhrase[] = await dispatch( - "FETCH_MORA_DATA", - { - accentPhrases, - engineId, - styleId, - } - ); - commit("COMMAND_MULTI_CHANGE_VOICE", { - audioKeys, - voice, - update: "AccentPhrases", - accentPhrases: newAccentPhrases, - }); - } else { - const text = state.audioItems[audioKey].text; - const query: AudioQuery = await dispatch("FETCH_AUDIO_QUERY", { - text: text, - engineId, - styleId, - }); - commit("COMMAND_MULTI_CHANGE_VOICE", { - audioKeys, - voice, - update: "AudioQuery", - query, - }); - } - } catch (error) { - commit("COMMAND_MULTI_CHANGE_VOICE", { - audioKeys, - voice, - update: "RollbackStyleId", + const errors: Record = {}; + const changes: Record< + AudioKey, + | { + update: "AccentPhrases"; + accentPhrases: AccentPhrase[]; + } + | { + update: "AudioQuery"; + query: AudioQuery; + } + | { + update: "OnlyVoice"; + } + > = {}; + + for (const audioKey of audioKeys) { + try { + const audioItem = state.audioItems[audioKey]; + if (audioItem.query == undefined) { + const query: AudioQuery = await dispatch("FETCH_AUDIO_QUERY", { + text: audioItem.text, + engineId: voice.engineId, + styleId: voice.styleId, }); - throw error; + changes[audioKey] = { + update: "AudioQuery", + query, + }; + } else { + const newAccentPhrases: AccentPhrase[] = await dispatch( + "FETCH_MORA_DATA", + { + accentPhrases: audioItem.query.accentPhrases, + engineId: voice.engineId, + styleId: voice.styleId, + } + ); + + changes[audioKey] = { + update: "AccentPhrases", + accentPhrases: newAccentPhrases, + }; } - }) - ); + } catch (error) { + errors[audioKey] = error; + changes[audioKey] = { + update: "OnlyVoice", + }; + } + } + + commit("COMMAND_MULTI_CHANGE_VOICE", { + voice, + changes, + }); + + if (Object.keys(errors).length > 0) { + throw new Error( + `話者の変更に失敗しました:\n${Object.entries(errors) + .map(([audioKey, error]) => `${audioKey}:${error}`) + .join("\n")}` + ); + } }, }, diff --git a/src/store/type.ts b/src/store/type.ts index 218269ef22..b7006cda73 100644 --- a/src/store/type.ts +++ b/src/store/type.ts @@ -502,17 +502,23 @@ export type AudioCommandStoreTypes = { }; COMMAND_MULTI_CHANGE_VOICE: { - mutation: { audioKeys: AudioKey[]; voice: Voice } & ( - | { update: "RollbackStyleId" } - | { - update: "AccentPhrases"; - accentPhrases: AccentPhrase[]; - } - | { - update: "AudioQuery"; - query: AudioQuery; - } - ); + mutation: { + voice: Voice; + changes: Record< + AudioKey, + | { + update: "AccentPhrases"; + accentPhrases: AccentPhrase[]; + } + | { + update: "AudioQuery"; + query: AudioQuery; + } + | { + update: "OnlyVoice"; + } + >; + }; action(payload: { audioKeys: AudioKey[]; voice: Voice }): void; };