Skip to content

Commit 9bcdcb9

Browse files
refactor: FrameAudioQueryの生成と音声合成の処理をaction化 (#2641)
Co-authored-by: Copilot <[email protected]>
1 parent 9162c7a commit 9bcdcb9

File tree

2 files changed

+148
-85
lines changed

2 files changed

+148
-85
lines changed

src/store/singing.ts

Lines changed: 131 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1526,39 +1526,6 @@ export const singingStore = createPartialStore<SingingStoreTypes>({
15261526
};
15271527
};
15281528

1529-
const fetchQuery = async (
1530-
engineId: EngineId,
1531-
engineFrameRate: number,
1532-
notesForRequestToEngine: NoteForRequestToEngine[],
1533-
) => {
1534-
try {
1535-
if (!getters.IS_ENGINE_READY(engineId)) {
1536-
throw new Error("Engine not ready.");
1537-
}
1538-
const instance = await actions.INSTANTIATE_ENGINE_CONNECTOR({
1539-
engineId,
1540-
});
1541-
const query = await instance.invoke("singFrameAudioQuery")({
1542-
score: { notes: notesForRequestToEngine },
1543-
speaker: singingTeacherStyleId,
1544-
});
1545-
const editorQuery: EditorFrameAudioQuery = {
1546-
...query,
1547-
frameRate: engineFrameRate,
1548-
};
1549-
return editorQuery;
1550-
} catch (error) {
1551-
const lyrics = notesForRequestToEngine
1552-
.map((value) => value.lyric)
1553-
.join("");
1554-
logger.error(
1555-
`Failed to fetch FrameAudioQuery. Lyrics of score are "${lyrics}".`,
1556-
error,
1557-
);
1558-
throw error;
1559-
}
1560-
};
1561-
15621529
const generateQuery = async (querySource: QuerySource) => {
15631530
const notesForRequestToEngine = createNotesForRequestToEngine(
15641531
querySource.firstRestDuration,
@@ -1574,11 +1541,12 @@ export const singingStore = createPartialStore<SingingStoreTypes>({
15741541
-querySource.keyRangeAdjustment,
15751542
);
15761543

1577-
const query = await fetchQuery(
1578-
querySource.engineId,
1579-
querySource.engineFrameRate,
1580-
notesForRequestToEngine,
1581-
);
1544+
const query = await actions.FETCH_SING_FRAME_AUDIO_QUERY({
1545+
engineId: querySource.engineId,
1546+
styleId: singingTeacherStyleId,
1547+
engineFrameRate: querySource.engineFrameRate,
1548+
notes: notesForRequestToEngine,
1549+
});
15821550

15831551
shiftPitch(query.f0, querySource.keyRangeAdjustment);
15841552
return query;
@@ -1994,30 +1962,11 @@ export const singingStore = createPartialStore<SingingStoreTypes>({
19941962
const synthesizeSingingVoice = async (
19951963
singingVoiceSource: SingingVoiceSource,
19961964
) => {
1997-
const singer = singingVoiceSource.singer;
1998-
const query = singingVoiceSource.queryForSingingVoiceSynthesis;
1999-
2000-
if (!getters.IS_ENGINE_READY(singer.engineId)) {
2001-
throw new Error("Engine not ready.");
2002-
}
2003-
try {
2004-
const instance = await actions.INSTANTIATE_ENGINE_CONNECTOR({
2005-
engineId: singer.engineId,
2006-
});
2007-
return await instance.invoke("frameSynthesis")({
2008-
frameAudioQuery: query,
2009-
speaker: singer.styleId,
2010-
});
2011-
} catch (error) {
2012-
const phonemes = query.phonemes
2013-
.map((value) => value.phoneme)
2014-
.join(" ");
2015-
logger.error(
2016-
`Failed to synthesis. Phonemes are "${phonemes}".`,
2017-
error,
2018-
);
2019-
throw error;
2020-
}
1965+
return await actions.FRAME_SYNTHESIS({
1966+
query: singingVoiceSource.queryForSingingVoiceSynthesis,
1967+
engineId: singingVoiceSource.singer.engineId,
1968+
styleId: singingVoiceSource.singer.styleId,
1969+
});
20211970
};
20221971

20231972
const singingVoiceSynthesisStage: PhraseRenderStage = {
@@ -2394,9 +2343,47 @@ export const singingStore = createPartialStore<SingingStoreTypes>({
23942343
}),
23952344
},
23962345

2346+
FETCH_SING_FRAME_AUDIO_QUERY: {
2347+
async action(
2348+
{ getters, actions },
2349+
{
2350+
notes,
2351+
engineFrameRate,
2352+
engineId,
2353+
styleId,
2354+
}: {
2355+
notes: NoteForRequestToEngine[];
2356+
engineFrameRate: number;
2357+
engineId: EngineId;
2358+
styleId: StyleId;
2359+
},
2360+
) {
2361+
try {
2362+
if (!getters.IS_ENGINE_READY(engineId)) {
2363+
throw new Error("Engine not ready.");
2364+
}
2365+
const instance = await actions.INSTANTIATE_ENGINE_CONNECTOR({
2366+
engineId,
2367+
});
2368+
const query = await instance.invoke("singFrameAudioQuery")({
2369+
score: { notes },
2370+
speaker: styleId,
2371+
});
2372+
return { ...query, frameRate: engineFrameRate };
2373+
} catch (error) {
2374+
const lyrics = notes.map((value) => value.lyric).join("");
2375+
logger.error(
2376+
`Failed to fetch FrameAudioQuery. Lyrics of score are "${lyrics}".`,
2377+
error,
2378+
);
2379+
throw error;
2380+
}
2381+
},
2382+
},
2383+
23972384
FETCH_SING_FRAME_F0: {
23982385
async action(
2399-
{ actions },
2386+
{ getters, actions },
24002387
{
24012388
notes,
24022389
query,
@@ -2409,24 +2396,36 @@ export const singingStore = createPartialStore<SingingStoreTypes>({
24092396
styleId: StyleId;
24102397
},
24112398
) {
2412-
const instance = await actions.INSTANTIATE_ENGINE_CONNECTOR({
2413-
engineId,
2414-
});
2415-
return await instance.invoke("singFrameF0")({
2416-
bodySingFrameF0SingFrameF0Post: {
2417-
score: {
2418-
notes,
2399+
try {
2400+
if (!getters.IS_ENGINE_READY(engineId)) {
2401+
throw new Error("Engine not ready.");
2402+
}
2403+
const instance = await actions.INSTANTIATE_ENGINE_CONNECTOR({
2404+
engineId,
2405+
});
2406+
return await instance.invoke("singFrameF0")({
2407+
bodySingFrameF0SingFrameF0Post: {
2408+
score: {
2409+
notes,
2410+
},
2411+
frameAudioQuery: query,
24192412
},
2420-
frameAudioQuery: query,
2421-
},
2422-
speaker: styleId,
2423-
});
2413+
speaker: styleId,
2414+
});
2415+
} catch (error) {
2416+
const lyrics = notes.map((value) => value.lyric).join("");
2417+
logger.error(
2418+
`Failed to fetch sing frame f0. Lyrics of score are "${lyrics}".`,
2419+
error,
2420+
);
2421+
throw error;
2422+
}
24242423
},
24252424
},
24262425

24272426
FETCH_SING_FRAME_VOLUME: {
24282427
async action(
2429-
{ actions },
2428+
{ getters, actions },
24302429
{
24312430
notes,
24322431
query,
@@ -2439,18 +2438,65 @@ export const singingStore = createPartialStore<SingingStoreTypes>({
24392438
styleId: StyleId;
24402439
},
24412440
) {
2442-
const instance = await actions.INSTANTIATE_ENGINE_CONNECTOR({
2443-
engineId,
2444-
});
2445-
return await instance.invoke("singFrameVolume")({
2446-
bodySingFrameVolumeSingFrameVolumePost: {
2447-
score: {
2448-
notes,
2441+
try {
2442+
if (!getters.IS_ENGINE_READY(engineId)) {
2443+
throw new Error("Engine not ready.");
2444+
}
2445+
const instance = await actions.INSTANTIATE_ENGINE_CONNECTOR({
2446+
engineId,
2447+
});
2448+
return await instance.invoke("singFrameVolume")({
2449+
bodySingFrameVolumeSingFrameVolumePost: {
2450+
score: {
2451+
notes,
2452+
},
2453+
frameAudioQuery: query,
24492454
},
2455+
speaker: styleId,
2456+
});
2457+
} catch (error) {
2458+
const lyrics = notes.map((value) => value.lyric).join("");
2459+
logger.error(
2460+
`Failed to fetch sing frame volume. Lyrics of score are "${lyrics}".`,
2461+
error,
2462+
);
2463+
throw error;
2464+
}
2465+
},
2466+
},
2467+
2468+
FRAME_SYNTHESIS: {
2469+
async action(
2470+
{ getters, actions },
2471+
{
2472+
query,
2473+
engineId,
2474+
styleId,
2475+
}: {
2476+
query: EditorFrameAudioQuery;
2477+
engineId: EngineId;
2478+
styleId: StyleId;
2479+
},
2480+
) {
2481+
if (!getters.IS_ENGINE_READY(engineId)) {
2482+
throw new Error("Engine not ready.");
2483+
}
2484+
try {
2485+
const instance = await actions.INSTANTIATE_ENGINE_CONNECTOR({
2486+
engineId,
2487+
});
2488+
return await instance.invoke("frameSynthesis")({
24502489
frameAudioQuery: query,
2451-
},
2452-
speaker: styleId,
2453-
});
2490+
speaker: styleId,
2491+
});
2492+
} catch (error) {
2493+
const phonemes = query.phonemes.map((value) => value.phoneme).join(" ");
2494+
logger.error(
2495+
`Failed to synthesize. Phonemes are "${phonemes}".`,
2496+
error,
2497+
);
2498+
throw error;
2499+
}
24542500
},
24552501
},
24562502

src/store/type.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,6 +1190,15 @@ export type SingingStoreTypes = {
11901190
action(): void;
11911191
};
11921192

1193+
FETCH_SING_FRAME_AUDIO_QUERY: {
1194+
action(payload: {
1195+
notes: NoteForRequestToEngine[];
1196+
engineFrameRate: number;
1197+
engineId: EngineId;
1198+
styleId: StyleId;
1199+
}): Promise<EditorFrameAudioQuery>;
1200+
};
1201+
11931202
FETCH_SING_FRAME_F0: {
11941203
action(payload: {
11951204
notes: NoteForRequestToEngine[];
@@ -1208,6 +1217,14 @@ export type SingingStoreTypes = {
12081217
}): Promise<number[]>;
12091218
};
12101219

1220+
FRAME_SYNTHESIS: {
1221+
action(payload: {
1222+
query: EditorFrameAudioQuery;
1223+
engineId: EngineId;
1224+
styleId: StyleId;
1225+
}): Promise<Blob>;
1226+
};
1227+
12111228
TICK_TO_SECOND: {
12121229
getter(position: number): number;
12131230
};

0 commit comments

Comments
 (0)