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

整理: Character 内部型を追加 #1320

Merged
merged 8 commits into from
Jun 2, 2024
Merged
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
88 changes: 70 additions & 18 deletions voicevox_engine/metas/MetasStore.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import json
from copy import deepcopy
from dataclasses import dataclass
from pathlib import Path
from typing import Literal
from typing import Final, Literal

from pydantic import BaseModel, Field

Expand All @@ -11,7 +11,6 @@
SpeakerStyle,
SpeakerSupportedFeatures,
StyleId,
StyleType,
)


Expand Down Expand Up @@ -105,24 +104,77 @@ def construct_lookup(
return lookup_table


@dataclass
class Character:
"""キャラクター"""

name: str
uuid: str
talk_styles: list[SpeakerStyle]
sing_styles: list[SpeakerStyle]
version: str
supported_features: SpeakerSupportedFeatures


TALK_STYLE_TYPES: Final = ["talk"]
SING_STYLE_TYPES: Final = ["singing_teacher", "frame_decode", "sing"]


def filter_speakers_and_styles(
speakers: list[Speaker],
speaker_or_singer: Literal["speaker", "singer"],
) -> list[Speaker]:
"""
話者・スタイルをフィルタリングする。
speakerの場合はトーク系スタイルのみ、singerの場合はソング系スタイルのみを残す。
スタイル数が0になった話者は除外する。
"""
style_types: list[StyleType]
"""キャラクター内のスタイルをtalk系・sing系のみにする。スタイル数が0になったキャラクターは除外する。"""

characters = map(
lambda speaker: Character(
name=speaker.name,
uuid=speaker.speaker_uuid,
talk_styles=list(
filter(lambda style: style.type in TALK_STYLE_TYPES, speaker.styles)
),
sing_styles=list(
filter(lambda style: style.type in SING_STYLE_TYPES, speaker.styles)
),
version=speaker.version,
supported_features=speaker.supported_features,
),
speakers,
)

if speaker_or_singer == "speaker":
style_types = ["talk"]
# talk 系スタイルを持たないキャラクターを除外する
talk_characters = filter(
lambda character: len(character.talk_styles) > 0, characters
)
# キャラクター内のスタイルを talk 系のみにしたうえでキャストする
talk_speakers = map(
lambda talker: Speaker(
name=talker.name,
speaker_uuid=talker.uuid,
styles=talker.talk_styles,
version=talker.version,
supported_features=talker.supported_features,
),
talk_characters,
)
return list(talk_speakers)
elif speaker_or_singer == "singer":
style_types = ["singing_teacher", "frame_decode", "sing"]

speakers = deepcopy(speakers)
for speaker in speakers:
speaker.styles = [
style for style in speaker.styles if style.type in style_types
]
return [speaker for speaker in speakers if len(speaker.styles) > 0]
# sing 系スタイルを持たないキャラクターを除外する
sing_characters = filter(
lambda character: len(character.sing_styles) > 0, characters
)
# キャラクター内のスタイルを sing 系のみにしたうえでキャストする
sing_speakers = map(
lambda singer: Speaker(
name=singer.name,
speaker_uuid=singer.uuid,
styles=singer.sing_styles,
version=singer.version,
supported_features=singer.supported_features,
),
sing_characters,
)
return list(sing_speakers)
else:
raise Exception(f"'{speaker_or_singer}' は不正な style_type です")
tarepan marked this conversation as resolved.
Show resolved Hide resolved