Skip to content

Commit

Permalink
feat!: "話者" ("speaker") → "キャラクター" ("character")
Browse files Browse the repository at this point in the history
  • Loading branch information
qryxip committed Jan 25, 2025
1 parent 0cfbf94 commit 2a9733f
Show file tree
Hide file tree
Showing 17 changed files with 98 additions and 98 deletions.
2 changes: 1 addition & 1 deletion crates/voicevox_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ pub use self::{
devices::SupportedDevices,
engine::{wav_from_s16le, AccentPhrase, AudioQuery, Mora},
error::{Error, ErrorKind},
metas::{SpeakerMeta, SpeakerVersion, StyleId, StyleMeta, StyleType, VoiceModelMeta},
metas::{CharacterMeta, CharacterVersion, StyleId, StyleMeta, StyleType, VoiceModelMeta},
result::Result,
synthesizer::AccelerationMode,
user_dict::{UserDictWord, UserDictWordType},
Expand Down
60 changes: 30 additions & 30 deletions crates/voicevox_core/src/metas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,28 @@ use itertools::Itertools as _;
use serde::{Deserialize, Serialize};
use tracing::warn;

/// [`speaker_uuid`]をキーとして複数の[`SpeakerMeta`]をマージする。
/// [`speaker_uuid`]をキーとして複数の[`CharacterMeta`]をマージする。
///
/// マージする際話者は[`SpeakerMeta::order`]、スタイルは[`StyleMeta::order`]をもとに安定ソートされる。
/// `order`が無い話者とスタイルは、そうでないものよりも後ろに置かれる。
/// マージする際キャラクターは[`CharacterMeta::order`]、スタイルは[`StyleMeta::order`]をもとに安定ソートされる。
/// `order`が無いキャラクターとスタイルは、そうでないものよりも後ろに置かれる。
///
/// [`speaker_uuid`]: SpeakerMeta::speaker_uuid
pub fn merge<'a>(metas: impl IntoIterator<Item = &'a SpeakerMeta>) -> Vec<SpeakerMeta> {
/// [`speaker_uuid`]: CharacterMeta::speaker_uuid
pub fn merge<'a>(metas: impl IntoIterator<Item = &'a CharacterMeta>) -> Vec<CharacterMeta> {
return metas
.into_iter()
.fold(IndexMap::<_, SpeakerMeta>::new(), |mut acc, speaker| {
acc.entry(&speaker.speaker_uuid)
.and_modify(|acc| acc.styles.extend(speaker.styles.clone()))
.or_insert_with(|| speaker.clone());
.fold(IndexMap::<_, CharacterMeta>::new(), |mut acc, character| {
acc.entry(&character.speaker_uuid)
.and_modify(|acc| acc.styles.extend(character.styles.clone()))
.or_insert_with(|| character.clone());
acc
})
.into_values()
.update(|speaker| {
speaker
.update(|character| {
character
.styles
.sort_by_key(|&StyleMeta { order, .. }| key(order));
})
.sorted_by_key(|&SpeakerMeta { order, .. }| key(order))
.sorted_by_key(|&CharacterMeta { order, .. }| key(order))
.collect();

fn key(order: Option<u32>) -> impl Ord {
Expand All @@ -39,9 +39,9 @@ pub fn merge<'a>(metas: impl IntoIterator<Item = &'a SpeakerMeta>) -> Vec<Speake

/// スタイルID。
///
/// VOICEVOXにおける、ある[**話者**(_speaker_)]のある[**スタイル**(_style_)]を指す。
/// VOICEVOXにおける、ある[**キャラクター**]のある[**スタイル**(_style_)]を指す。
///
/// [**話者**(_speaker_)]: SpeakerMeta
/// [**キャラクター**]: CharacterMeta
/// [**スタイル**(_style_)]: StyleMeta
#[derive(
PartialEq,
Expand All @@ -65,40 +65,40 @@ impl Display for StyleId {
}
}

/// [**話者**(_speaker_)]のバージョン。
/// [**キャラクター**]のバージョン。
///
/// [**話者**(_speaker_)]: SpeakerMeta
/// [**キャラクター**]: CharacterMeta
#[derive(PartialEq, Eq, Clone, Ord, PartialOrd, Deserialize, Serialize, new, Debug)]
pub struct SpeakerVersion(pub String);
pub struct CharacterVersion(pub String);

impl Display for SpeakerVersion {
impl Display for CharacterVersion {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}

/// 音声モデルのメタ情報。
pub type VoiceModelMeta = Vec<SpeakerMeta>;
pub type VoiceModelMeta = Vec<CharacterMeta>;

/// **話者**(_speaker_)のメタ情報
/// キャラクターのメタ情報
#[derive(Deserialize, Serialize, Clone)]
#[non_exhaustive]
pub struct SpeakerMeta {
/// 話者名
pub struct CharacterMeta {
/// キャラクター名
pub name: String,
/// 話者に属するスタイル
/// キャラクターに属するスタイル
pub styles: Vec<StyleMeta>,
/// 話者のバージョン
pub version: SpeakerVersion,
/// 話者のUUID
/// キャラクターのバージョン
pub version: CharacterVersion,
/// キャラクターのUUID
pub speaker_uuid: String,
/// 話者の順番
/// キャラクターの順番
///
/// `SpeakerMeta`の列は、この値に対して昇順に並んでいるべきである。
/// `CharacterMeta`の列は、この値に対して昇順に並んでいるべきである。
pub order: Option<u32>,
}

impl SpeakerMeta {
impl CharacterMeta {
/// # Panics
///
/// `speaker_uuid`が異なるときパニックする。
Expand Down Expand Up @@ -153,7 +153,7 @@ pub struct StyleMeta {
pub r#type: StyleType,
/// スタイルの順番。
///
/// [`SpeakerMeta::styles`]は、この値に対して昇順に並んでいるべきである。
/// [`CharacterMeta::styles`]は、この値に対して昇順に並んでいるべきである。
pub order: Option<u32>,
}

Expand Down
16 changes: 8 additions & 8 deletions crates/voicevox_core/src/status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use crate::{
InferenceSignature,
},
manifest::{InnerVoiceId, StyleIdToInnerVoiceId},
metas::{self, SpeakerMeta, StyleId, StyleMeta, VoiceModelMeta},
metas::{self, CharacterMeta, StyleId, StyleMeta, VoiceModelMeta},
voice_model::{ModelBytesWithInnerVoiceIdsByDomain, VoiceModelHeader, VoiceModelId},
Result,
};
Expand Down Expand Up @@ -163,7 +163,7 @@ impl<R: InferenceRuntime> LoadedModels<R> {
.find(|(_, LoadedModel { metas, .. })| {
metas
.iter()
.flat_map(|SpeakerMeta { styles, .. }| styles)
.flat_map(|CharacterMeta { styles, .. }| styles)
.any(|style| style.id == style_id && D::style_types().contains(&style.r#type))
})
.ok_or(ErrorRepr::StyleNotFound {
Expand Down Expand Up @@ -214,7 +214,7 @@ impl<R: InferenceRuntime> LoadedModels<R> {
.find(|(_, LoadedModel { metas, .. })| {
metas
.iter()
.flat_map(|SpeakerMeta { styles, .. }| styles)
.flat_map(|CharacterMeta { styles, .. }| styles)
.any(|style| style.id == style_id && D::style_types().contains(&style.r#type))
})
.and_then(
Expand Down Expand Up @@ -263,7 +263,7 @@ impl<R: InferenceRuntime> LoadedModels<R> {

// FIXME: https://github.com/VOICEVOX/voicevox_core/pull/761#discussion_r1590200343

let loaded = self.speakers();
let loaded = self.characters();
let external = model_header.metas.iter();
for (loaded, external) in iproduct!(loaded, external) {
if loaded.speaker_uuid == external.speaker_uuid {
Expand All @@ -275,7 +275,7 @@ impl<R: InferenceRuntime> LoadedModels<R> {
let external = model_header
.metas
.iter()
.flat_map(|speaker| &speaker.styles)
.flat_map(|CharacterMeta { styles, .. }| styles)
.map(|&StyleMeta { id, .. }| id);
if let Some((id, _)) =
iproduct!(loaded, external).find(|(loaded, external)| loaded == external)
Expand Down Expand Up @@ -310,13 +310,13 @@ impl<R: InferenceRuntime> LoadedModels<R> {
Ok(())
}

fn speakers(&self) -> impl Iterator<Item = &SpeakerMeta> + Clone {
fn characters(&self) -> impl Iterator<Item = &CharacterMeta> + Clone {
self.0.values().flat_map(|LoadedModel { metas, .. }| metas)
}

fn styles(&self) -> impl Iterator<Item = &StyleMeta> {
self.speakers()
.flat_map(|SpeakerMeta { styles, .. }| styles)
self.characters()
.flat_map(|CharacterMeta { styles, .. }| styles)
}
}

Expand Down
18 changes: 9 additions & 9 deletions crates/voicevox_core/src/voice_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use crate::{
InferenceDomain,
},
manifest::{Manifest, ManifestDomains, ModelFile, ModelFileType, StyleIdToInnerVoiceId},
SpeakerMeta, StyleMeta, StyleType, VoiceModelMeta,
CharacterMeta, StyleMeta, StyleType, VoiceModelMeta,
};

pub(crate) type ModelBytesWithInnerVoiceIdsByDomain = inference_domain_map_values!(
Expand Down Expand Up @@ -530,10 +530,10 @@ impl InferenceDomainMap<ManifestDomains> {
/// manifestとして対応していない`StyleType`に対してエラーを発する。
///
/// `Status`はこのバリデーションを信頼し、`InferenceDomain`の不足時にパニックする。
fn check_acceptable(&self, metas: &[SpeakerMeta]) -> std::result::Result<(), StyleType> {
fn check_acceptable(&self, metas: &[CharacterMeta]) -> std::result::Result<(), StyleType> {
let err = metas
.iter()
.flat_map(|SpeakerMeta { styles, .. }| styles)
.flat_map(|CharacterMeta { styles, .. }| styles)
.map(|StyleMeta { r#type, .. }| *r#type)
.unique()
.find(|&style_type| !self.accepts(style_type));
Expand Down Expand Up @@ -673,7 +673,7 @@ mod tests {
ExperimentalTalkManifest, FrameDecodeManifest, ManifestDomains, SingingTeacherManifest,
TalkManifest,
},
SpeakerMeta, StyleType,
CharacterMeta, StyleType,
};

#[rstest]
Expand All @@ -694,7 +694,7 @@ mod tests {
singing_teacher: Some(SingingTeacherManifest::default()),
frame_decode: Some(FrameDecodeManifest::default()),
},
&[speaker(&[StyleType::Talk])],
&[character(&[StyleType::Talk])],
Ok(())
)]
#[case(
Expand All @@ -704,7 +704,7 @@ mod tests {
singing_teacher: Some(SingingTeacherManifest::default()),
frame_decode: Some(FrameDecodeManifest::default()),
},
&[speaker(&[StyleType::Talk, StyleType::Sing])],
&[character(&[StyleType::Talk, StyleType::Sing])],
Ok(())
)]
#[case(
Expand All @@ -714,19 +714,19 @@ mod tests {
singing_teacher: None,
frame_decode: None,
},
&[speaker(&[StyleType::Talk])],
&[character(&[StyleType::Talk])],
Err(())
)]
fn check_acceptable_works(
#[case] manifest: &InferenceDomainMap<ManifestDomains>,
#[case] metas: &[SpeakerMeta],
#[case] metas: &[CharacterMeta],
#[case] expected: std::result::Result<(), ()>,
) {
let actual = manifest.check_acceptable(metas).map_err(|_| ());
assert_eq!(expected, actual);
}

fn speaker(style_types: &'static [StyleType]) -> SpeakerMeta {
fn character(style_types: &'static [StyleType]) -> CharacterMeta {
let styles = style_types
.iter()
.map(|style_type| {
Expand Down
2 changes: 1 addition & 1 deletion crates/voicevox_core_c_api/include/voicevox_core.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions crates/voicevox_core_c_api/src/c_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use camino::Utf8Path;
use duplicate::duplicate_item;
use easy_ext::ext;
use ref_cast::ref_cast_custom;
use voicevox_core::{Result, SpeakerMeta, VoiceModelId};
use voicevox_core::{CharacterMeta, Result, VoiceModelId};

use crate::{
helpers::CApiResult,
Expand Down Expand Up @@ -132,7 +132,7 @@ impl *const VoicevoxVoiceModelFile {
}
}

fn metas_to_json(metas: &[SpeakerMeta]) -> CString {
fn metas_to_json(metas: &[CharacterMeta]) -> CString {
let metas = serde_json::to_string(metas).expect("should not fail");
CString::new(metas).expect("should not contain NUL")
}
Expand Down
2 changes: 1 addition & 1 deletion crates/voicevox_core_c_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ pub type VoicevoxVoiceModelId<'a> = &'a [u8; 16];

/// スタイルID。
///
/// VOICEVOXにおける、ある<b>話者</b>(_speaker_)のある<b>スタイル</b>(_style_)を指す。
/// VOICEVOXにおける、ある<b>キャラクター</b>のある<b>スタイル</b>(_style_)を指す。
pub type VoicevoxStyleId = u32;

// TODO: cbindgenが`#[unsafe(no_mangle)]`に対応したら`#[no_mangle]`を置き換える
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,43 +5,43 @@
import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;

/** 話者(speaker)のメタ情報。 */
public class SpeakerMeta {
/** 話者名。 */
/** キャラクターのメタ情報。 */
public class CharacterMeta {
/** キャラクター名。 */
@SerializedName("name")
@Expose
@Nonnull
public final String name;

/** 話者に属するスタイル。 */
/** キャラクターに属するスタイル。 */
@SerializedName("styles")
@Expose
@Nonnull
public final StyleMeta[] styles;

/** 話者のUUID。 */
/** キャラクターのUUID。 */
@SerializedName("speaker_uuid")
@Expose
@Nonnull
public final String speakerUuid;

/** 話者のバージョン。 */
/** キャラクターのバージョン。 */
@SerializedName("version")
@Expose
@Nonnull
public final String version;

/**
* 話者の順番
* キャラクターの順番
*
* <p>{@code SpeakerMeta}の列は、この値に対して昇順に並んでいるべきである。
* <p>{@code CharacterMeta}の列は、この値に対して昇順に並んでいるべきである。
*/
@SerializedName("order")
@Expose
@Nullable
public final Integer order;

private SpeakerMeta() {
private CharacterMeta() {
// GSONからコンストラクトするため、このメソッドは呼ばれることは無い。
// このメソッドは@Nonnullを満たすために必要。
this.name = "";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ public class StyleMeta {
public final StyleType type;

/**
* 話者の順番
* スタイルの順番
*
* <p>{@link SpeakerMeta#styles}の列は、この値に対して昇順に並んでいるべきである。
* <p>{@link CharacterMeta#styles}の列は、この値に対して昇順に並んでいるべきである。
*/
@SerializedName("order")
@Expose
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import jp.hiroshiba.voicevoxcore.AccelerationMode;
import jp.hiroshiba.voicevoxcore.AccentPhrase;
import jp.hiroshiba.voicevoxcore.AudioQuery;
import jp.hiroshiba.voicevoxcore.SpeakerMeta;
import jp.hiroshiba.voicevoxcore.CharacterMeta;
import jp.hiroshiba.voicevoxcore.exceptions.InvalidModelDataException;
import jp.hiroshiba.voicevoxcore.exceptions.RunModelException;
import jp.hiroshiba.voicevoxcore.internal.Dll;
Expand Down Expand Up @@ -63,10 +63,10 @@ public boolean isGpuMode() {
* @return メタ情報。
*/
@Nonnull
public SpeakerMeta[] metas() {
public CharacterMeta[] metas() {
Gson gson = new Gson();
String metasJson = rsGetMetasJson();
SpeakerMeta[] rawMetas = gson.fromJson(metasJson, SpeakerMeta[].class);
CharacterMeta[] rawMetas = gson.fromJson(metasJson, CharacterMeta[].class);
if (rawMetas == null) {
throw new NullPointerException("metas");
}
Expand Down
Loading

0 comments on commit 2a9733f

Please sign in to comment.