Skip to content

Commit

Permalink
コメントを微調整
Browse files Browse the repository at this point in the history
  • Loading branch information
Hiroshiba committed Dec 15, 2024
1 parent 6ebdb48 commit aecae0b
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 59 deletions.
52 changes: 28 additions & 24 deletions src/mock/engineMock/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,42 @@
## 概要

通信を介さずに音声合成できるエンジンのモックです。
エンジンのOpenAPIから自動生成されたインターフェイス`DefaultApi`を継承しています。

同じ入力には同じ出力を返し、別の入力には別の出力を返すようになっています。
また出力を見たときにUIや処理の実装の異常に気付けるように、ある程度直感に合う出力を返すよう努力されています。
また出力を見たときにUIや処理の実装の異常に気付けるように、ある程度直感に合う出力を返すよう努力されています。

例:音量を下げると音声が小さくなる、音程と周波数が一致する、など。

モックの実装は気軽に破壊的変更しても問題ありません。

## 実装ポリシー
## ビルド戦略

ブラウザ版でも使えるように実装されています
モックエンジンの取り扱いポリシーはこんな感じです
ブラウザ版でも使えるようにすべく、ソフトウェアにも組み込める形で実装されています
ビルド時のモックエンジンの取り扱いポリシーはこんな感じです

- Electronビルド成果物
- モックエンジン関連の重いファイルはなるべく含まれないようにする
- 形態素解析の辞書ファイルやダミー画像など
- モックエンジン関連の重い処理が一切実行されないようにする
- 形態素解析の辞書の初期化、画像の読み込みなど
- 重い処理が一切実行されないようにする
- 辞書の初期化、画像の読み込みなど
- なるべく重いファイルはビルドに含まれないようにする
- 形態素解析の辞書ファイルやダミー画像など

## ファイル構成

- `talkModelMock`
- トーク用の音声クエリを作るまでの処理
- `singModelMock`
- ソング用の音声クエリを作るまでの処理
- `audioQueryMock`
- 音声クエリを作る
- `synthesisMock`
- 音声波形の合成
- `characterResourceMock`
- キャラ名や画像などのリソース
- `phonemeMock`
- 音素
- `manifestMock`
- エンジンのマニフェスト
- `talkModelMock.ts`
- トーク用の音声クエリを作るまでの処理周り
- `singModelMock.ts`
- ソング用の音声クエリを作るまでの処理周り
- `audioQueryMock.ts`
- 音声クエリ周り
- `synthesisMock.ts`
- 音声波形の合成周り
- `characterResourceMock.ts`
- キャラ名や画像などのリソース周り
- `phonemeMock.ts`
- 音素周り
- `manifestMock.ts`
- エンジンのマニフェスト周り

## kuromoji.jsについて

本家kuromoji.jsはパス操作周りでエラーが起こるので、フォーク版を使っています。
mock用途以外にkuromoji.jsを使う予定はなく、もし動かなくなった際は依存を切ることも検討します。
9 changes: 6 additions & 3 deletions src/mock/engineMock/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export function createOpenAPIEngineMock(): DefaultApiInterface {
return "mock";
},

// メタ情報
async engineManifestEngineManifestGet(): Promise<EngineManifest> {
return getEngineManifestMock();
},
Expand All @@ -57,6 +58,7 @@ export function createOpenAPIEngineMock(): DefaultApiInterface {
return { cpu: true, cuda: false, dml: false };
},

// キャラクター情報
async isInitializedSpeakerIsInitializedSpeakerGet(): Promise<boolean> {
return true;
},
Expand Down Expand Up @@ -85,6 +87,7 @@ export function createOpenAPIEngineMock(): DefaultApiInterface {
return getSpeakerInfoMock(paload.speakerUuid);
},

// トーク系
async audioQueryAudioQueryPost(
payload: AudioQueryAudioQueryPostRequest,
): Promise<AudioQuery> {
Expand Down Expand Up @@ -145,6 +148,7 @@ export function createOpenAPIEngineMock(): DefaultApiInterface {
return new Blob([buffer], { type: "audio/wav" });
},

// ソング系
async singFrameAudioQuerySingFrameAudioQueryPost(
payload: SingFrameAudioQuerySingFrameAudioQueryPostRequest,
): Promise<FrameAudioQuery> {
Expand Down Expand Up @@ -200,14 +204,13 @@ export function createOpenAPIEngineMock(): DefaultApiInterface {
},

// 辞書系

async getUserDictWordsUserDictGet(): Promise<{
[key: string]: UserDictWord;
}> {
// 空の辞書を返す
// ダミーで空の辞書を返す
return {};
},
};

return mockApi as DefaultApiInterface;
return mockApi satisfies Partial<DefaultApiInterface> as DefaultApiInterface;
}
4 changes: 3 additions & 1 deletion src/mock/engineMock/manifestMock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
* エンジンマニフェストのモック。
*/

import { EngineManifest } from "@/openapi";

/** エンジンマニフェストを返すモック */
export function getEngineManifestMock() {
return {
Expand Down Expand Up @@ -30,5 +32,5 @@ export function getEngineManifestMock() {
manageLibrary: false,
returnResourceUrl: true,
},
};
} satisfies EngineManifest;
}
1 change: 0 additions & 1 deletion src/mock/engineMock/singModelMock.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/**
* ソング系の構造体を作るモック。
* 値は適当だが、テストで使えるよう決定論的に決まるようにしたり、UIのバグに気づけるようある程度規則を持たせている。
*/

import { moraToPhonemes } from "./phonemeMock";
Expand Down
55 changes: 25 additions & 30 deletions src/mock/engineMock/talkModelMock.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,29 @@
/**
* ソング系の構造体を作るモック。
* 値は適当だが、テストで使えるよう決定論的に決まるようにしたり、UIのバグに気づけるようある程度規則を持たせている。
* トーク系の構造体を作るモック。
*/

import kuromoji, { IpadicFeatures, Tokenizer } from "kuromoji";
import { builder, IpadicFeatures, Tokenizer } from "kuromoji";
import { moraToPhonemes } from "./phonemeMock";
import { moraPattern } from "@/domain/japanese";
import { AccentPhrase, Mora } from "@/openapi";
import packageJson from "@/../package.json";

/** Nodeとして動いてほしいかを判定する */
const isNode =
// window.documentがなければNode
typeof window == "undefined" ||
typeof window.document == "undefined" ||
// happy-domのときはNode
typeof (window as { happyDOM?: unknown }).happyDOM != "undefined";

let _tokenizer: Tokenizer<IpadicFeatures> | undefined;

/** kuromoji用の辞書のパスを取得する */
function getDicPath() {
// ブラウザのときはCDNから辞書を取得し、Nodeのときはローカルから取得する

const pathForBrowser = `https://cdn.jsdelivr.net/npm/kuromoji@${packageJson.devDependencies.kuromoji}/dict`;
const pathForNode = "node_modules/kuromoji/dict";

// window.documentがなければNode
if (typeof window == "undefined" || typeof window.document == "undefined") {
return pathForNode;
if (isNode) {
return "node_modules/kuromoji/dict";
} else {
return "https://cdn.jsdelivr.net/npm/[email protected]/dict";
}

// happy-domのときはNode
if (typeof (window as { happyDOM?: unknown }).happyDOM != "undefined") {
return pathForNode;
}

// それ以外はブラウザ
return pathForBrowser;
}

/** テキストをトークン列に変換するトークナイザーを取得する */
Expand All @@ -39,16 +33,17 @@ async function createOrGetTokenizer() {
}

return new Promise<Tokenizer<IpadicFeatures>>((resolve, reject) => {
kuromoji
.builder({ dicPath: getDicPath() })
.build((err: Error, tokenizer: Tokenizer<IpadicFeatures>) => {
if (err) {
reject(err);
} else {
_tokenizer = tokenizer;
resolve(tokenizer);
}
});
builder({
dicPath: getDicPath(),
nodeOrBrowser: isNode ? "node" : "browser",
}).build((err: Error, tokenizer: Tokenizer<IpadicFeatures>) => {
if (err) {
reject(err);
} else {
_tokenizer = tokenizer;
resolve(tokenizer);
}
});
});
}

Expand Down

0 comments on commit aecae0b

Please sign in to comment.