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

整理: CoreAdapter.speakers 出力をモデル化 #1260

Merged
merged 7 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 1 addition & 2 deletions voicevox_engine/app/routers/speaker.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"""話者情報機能を提供する API Router"""

import base64
import json
import traceback
from pathlib import Path
from typing import Annotated, Literal
Expand Down Expand Up @@ -76,7 +75,7 @@ def _speaker_info(

# 該当話者を検索する
speakers = parse_obj_as(
list[Speaker], json.loads(core_manager.get_core(core_version).speakers)
list[Speaker], core_manager.get_core(core_version).speakers
)
speakers = filter_speakers_and_styles(speakers, speaker_or_singer)
speaker = next(
Expand Down
33 changes: 30 additions & 3 deletions voicevox_engine/core/core_adapter.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,39 @@
import json
import threading
from dataclasses import dataclass
from typing import Literal, NewType

import numpy as np
from numpy.typing import NDArray
from pydantic import BaseModel, Field

from ..metas.Metas import StyleId
from .core_wrapper import CoreWrapper, OldCoreError

CoreStyleId = NewType("CoreStyleId", int)
CoreStyleType = Literal["talk", "singing_teacher", "frame_decode", "sing"]


class CoreSpeakerStyle(BaseModel):
"""
話者のスタイル情報
"""

name: str
id: CoreStyleId
type: CoreStyleType | None = Field(default="talk")


class CoreSpeaker(BaseModel):
"""
コアに含まれる話者情報
"""

name: str
speaker_uuid: str
styles: list[CoreSpeakerStyle]
version: str = Field("話者のバージョン")


@dataclass(frozen=True)
class DeviceSupport:
Expand All @@ -34,9 +60,10 @@ def default_sampling_rate(self) -> int:
return self.core.default_sampling_rate

@property
def speakers(self) -> str:
"""話者情報(json文字列)"""
return self.core.metas()
def speakers(self) -> list[CoreSpeaker]:
"""話者情報"""
metas = self.core.metas()
return [CoreSpeaker(**speaker) for speaker in json.loads(metas)]

@property
def supported_devices(self) -> DeviceSupport | None:
Expand Down
37 changes: 5 additions & 32 deletions voicevox_engine/metas/MetasStore.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import json
from copy import deepcopy
from pathlib import Path
from typing import TYPE_CHECKING, Literal, NewType
from typing import Literal

from pydantic import BaseModel, Field

from voicevox_engine.core.core_adapter import CoreAdapter, CoreSpeakerStyle
from voicevox_engine.metas.Metas import (
Speaker,
SpeakerStyle,
Expand All @@ -13,43 +14,15 @@
StyleType,
)

if TYPE_CHECKING:
from voicevox_engine.core.core_adapter import CoreAdapter


_CoreStyleId = NewType("_CoreStyleId", int)
_CoreStyleType = Literal["talk", "singing_teacher", "frame_decode", "sing"]


class _CoreSpeakerStyle(BaseModel):
"""
話者のスタイル情報
"""

name: str
id: _CoreStyleId
type: _CoreStyleType | None = Field(default="talk")


def cast_styles(cores: list[_CoreSpeakerStyle]) -> list[SpeakerStyle]:
def cast_styles(cores: list[CoreSpeakerStyle]) -> list[SpeakerStyle]:
"""コアから取得したスタイル情報をエンジン形式へキャストする。"""
return [
SpeakerStyle(name=core.name, id=StyleId(core.id), type=core.type)
for core in cores
]


class _CoreSpeaker(BaseModel):
"""
コアに含まれる話者情報
"""

name: str
speaker_uuid: str
styles: list[_CoreSpeakerStyle]
version: str = Field("話者のバージョン")


class _EngineSpeaker(BaseModel):
"""
エンジンに含まれる話者情報
Expand Down Expand Up @@ -82,7 +55,7 @@ def __init__(self, engine_speakers_path: Path) -> None:

# FIXME: engineではなくlist[CoreSpeaker]を渡す形にすることで
# TTSEngineによる循環importを修正する
def load_combined_metas(self, core: "CoreAdapter") -> list[Speaker]:
def load_combined_metas(self, core: CoreAdapter) -> list[Speaker]:
"""
コアに含まれる話者メタ情報とエンジンに含まれる話者メタ情報を統合
Parameters
Expand All @@ -95,7 +68,7 @@ def load_combined_metas(self, core: "CoreAdapter") -> list[Speaker]:
エンジンとコアに含まれる話者メタ情報
"""
# コアに含まれる話者メタ情報の収集
core_metas = [_CoreSpeaker(**speaker) for speaker in json.loads(core.speakers)]
core_metas = core.speakers
# エンジンに含まれる話者メタ情報との統合
return [
Speaker(
Expand Down