Skip to content

Commit

Permalink
StyleMeta自体にorderを持たせる
Browse files Browse the repository at this point in the history
  • Loading branch information
qryxip committed Feb 6, 2024
1 parent d2f418d commit 4061678
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 111 deletions.
104 changes: 37 additions & 67 deletions crates/voicevox_core/src/metas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,17 @@ use std::fmt::{Debug, Display};

use derive_getters::Getters;
use derive_new::new;
use indexmap::{IndexMap, IndexSet};
use indexmap::IndexMap;
use itertools::Itertools as _;
use serde::{Deserialize, Serialize};
use tracing::warn;

/// [`speaker_uuid`]をキーとして複数の[`SpeakerMeta`]をマージする。
///
/// マージする際話者は[`speaker_order`]、スタイルは[`style_order`]をもとに安定ソートされる。
/// `speaker_order`が無い話者と`style_order`に属さないスタイルは、そうでないものよりも後ろに
/// 置かれる。
/// マージする際話者は[`SpeakerMeta::order`]、スタイルは[`StyleMeta::order`]をもとに安定ソートされる。
/// `order`が無い話者とスタイルは、そうでないものよりも後ろに置かれる。
///
/// [`speaker_uuid`]: SpeakerMeta::speaker_uuid
/// [`speaker_order`]: SpeakerMeta::speaker_order
/// [`style_order`]: SpeakerMeta::style_order
pub fn merge<'a>(metas: impl IntoIterator<Item = &'a SpeakerMeta>) -> Vec<SpeakerMeta> {
return metas
.into_iter()
Expand All @@ -27,14 +24,11 @@ pub fn merge<'a>(metas: impl IntoIterator<Item = &'a SpeakerMeta>) -> Vec<Speake
})
.into_values()
.update(|speaker| {
speaker.styles.sort_by_key(|StyleMeta { id, .. }| {
key(speaker
.style_order
.get_index_of(id)
.map(|i| i.try_into().unwrap()))
});
speaker
.styles
.sort_by_key(|&StyleMeta { order, .. }| key(order));
})
.sorted_by_key(|&SpeakerMeta { speaker_order, .. }| key(speaker_order))
.sorted_by_key(|&SpeakerMeta { order, .. }| key(order))
.collect();

fn key(order: Option<u32>) -> impl Ord {
Expand Down Expand Up @@ -108,14 +102,7 @@ pub struct SpeakerMeta {
/// 話者の順番。
///
/// `SpeakerMeta`の列は、この値に対して昇順に並んでいるべきである。
speaker_order: Option<u32>,
/// 話者に属するスタイルの順番。
///
/// [`styles`]はこの並びに沿うべきである。
///
/// [`styles`]: Self::styles
#[serde(default)]
style_order: IndexSet<StyleId>,
order: Option<u32>,
}

impl SpeakerMeta {
Expand All @@ -128,17 +115,15 @@ impl SpeakerMeta {
styles: _,
version: version1,
speaker_uuid: speaker_uuid1,
speaker_order: speaker_order1,
style_order: style_order1,
order: order1,
} = self;

let Self {
name: name2,
styles: _,
version: version2,
speaker_uuid: speaker_uuid2,
speaker_order: speaker_order2,
style_order: style_order2,
order: order2,
} = other;

if speaker_uuid1 != speaker_uuid2 {
Expand All @@ -147,13 +132,7 @@ impl SpeakerMeta {

warn_diff(speaker_uuid1, "name", name1, name2);
warn_diff(speaker_uuid1, "version", version1, version2);
warn_diff(
speaker_uuid1,
"speaker_order",
speaker_order1,
speaker_order2,
);
warn_diff(speaker_uuid1, "style_order", style_order1, style_order2);
warn_diff(speaker_uuid1, "order", order1, order2);

fn warn_diff<T: PartialEq + Debug>(
speaker_uuid: &str,
Expand All @@ -175,6 +154,10 @@ pub struct StyleMeta {
id: StyleId,
/// スタイル名。
name: String,
/// スタイルの順番。
///
/// [`SpeakerMeta::styles`]は、この値に対して昇順に並んでいるべきである。
order: Option<u32>,
}

#[cfg(test)]
Expand All @@ -191,53 +174,44 @@ mod tests {
"styles": [
{
"id": 3,
"name": "B_1"
"name": "B_1",
"order": 0
}
],
"version": "0.0.0",
"speaker_uuid": "f34ab151-c0f5-4e0a-9ad2-51ce30dba24d",
"speaker_order": 1,
"style_order": [
3
]
"order": 1
},
{
"name": "A",
"styles": [
{
"id": 2,
"name": "A_3"
"name": "A_3",
"order": 2
}
],
"version": "0.0.0",
"speaker_uuid": "d6fd707c-a451-48e9-8f00-fe9ee3bf6264",
"speaker_order": 0,
"style_order": [
1,
0,
2
]
"order": 0
},
{
"name": "A",
"styles": [
{
"id": 1,
"name": "A_1"
"name": "A_1",
"order": 0
},
{
"id": 0,
"name": "A_2"
"name": "A_2",
"order": 1
}
],
"version": "0.0.0",
"speaker_uuid": "d6fd707c-a451-48e9-8f00-fe9ee3bf6264",
"speaker_order": 0,
"style_order": [
1,
0,
2
]
"order": 0
}
])
});
Expand All @@ -249,46 +223,42 @@ mod tests {
"styles": [
{
"id": 1,
"name": "A_1"
"name": "A_1",
"order": 0
},
{
"id": 0,
"name": "A_2"
"name": "A_2",
"order": 1
},
{
"id": 2,
"name": "A_3"
"name": "A_3",
"order": 2
}
],
"version": "0.0.0",
"speaker_uuid": "d6fd707c-a451-48e9-8f00-fe9ee3bf6264",
"speaker_order": 0,
"style_order": [
1,
0,
2
]
"order": 0
},
{
"name": "B",
"styles": [
{
"id": 3,
"name": "B_1"
"name": "B_1",
"order": 0
}
],
"version": "0.0.0",
"speaker_uuid": "f34ab151-c0f5-4e0a-9ad2-51ce30dba24d",
"speaker_order": 1,
"style_order": [
3
]
"order": 1
}
])
});

let input = &serde_json::from_value::<Vec<_>>(INPUT.clone())?;
let actual = serde_json::to_value(&super::merge(input))?;
let actual = serde_json::to_value(super::merge(input))?;

pretty_assertions::assert_eq!(*EXPECTED, actual);
Ok(())
Expand Down
42 changes: 22 additions & 20 deletions crates/voicevox_core_c_api/tests/e2e/snapshots.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,43 +6,44 @@ metas = '''
"styles": [
{
"id": 0,
"name": "style1"
"name": "style1",
"order": null
}
],
"version": "0.0.1",
"speaker_uuid": "574bc678-8370-44be-b941-08e46e7b47d7",
"speaker_order": null,
"style_order": []
"order": null
},
{
"name": "dummy2",
"styles": [
{
"id": 1,
"name": "style2"
"name": "style2",
"order": null
}
],
"version": "0.0.1",
"speaker_uuid": "dd9ccd75-75f6-40ce-a3db-960cbed2e905",
"speaker_order": null,
"style_order": []
"order": null
},
{
"name": "dummy3",
"styles": [
{
"id": 302,
"name": "style3-1"
"name": "style3-1",
"order": null
},
{
"id": 303,
"name": "style3-2"
"name": "style3-2",
"order": null
}
],
"version": "0.0.1",
"speaker_uuid": "5d3d9aa9-88e5-4a96-8ef7-f13a3cad1cb3",
"speaker_order": null,
"style_order": []
"order": null
}
]'''
stderr.windows = '''
Expand Down Expand Up @@ -95,43 +96,44 @@ metas = '''
"styles": [
{
"id": 0,
"name": "style1"
"name": "style1",
"order": null
}
],
"version": "0.0.1",
"speaker_uuid": "574bc678-8370-44be-b941-08e46e7b47d7",
"speaker_order": null,
"style_order": []
"order": null
},
{
"name": "dummy2",
"styles": [
{
"id": 1,
"name": "style2"
"name": "style2",
"order": null
}
],
"version": "0.0.1",
"speaker_uuid": "dd9ccd75-75f6-40ce-a3db-960cbed2e905",
"speaker_order": null,
"style_order": []
"order": null
},
{
"name": "dummy3",
"styles": [
{
"id": 302,
"name": "style3-1"
"name": "style3-1",
"order": null
},
{
"id": 303,
"name": "style3-2"
"name": "style3-2",
"order": null
}
],
"version": "0.0.1",
"speaker_uuid": "5d3d9aa9-88e5-4a96-8ef7-f13a3cad1cb3",
"speaker_order": null,
"style_order": []
"order": null
}
]'''
stderr.windows = '''
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import com.google.gson.annotations.SerializedName;
import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;
import java.util.LinkedHashSet;

/** 音声モデル。 */
public class VoiceModel extends Dll {
Expand Down Expand Up @@ -75,20 +74,10 @@ public static class SpeakerMeta {
*
* <p>{@code SpeakerMeta}の列は、この値に対して昇順に並んでいるべきである。
*/
@SerializedName("speaker_order")
@SerializedName("order")
@Expose
@Nullable
public final Integer speakerOrder;

/**
* 話者に属するスタイルの順番。
*
* <p>{@link #styles}はこの並びに沿うべきである。
*/
@SerializedName("style_order")
@Expose
@Nonnull
public final LinkedHashSet<Integer> styleOrder;
public final Integer order;

private SpeakerMeta() {
// GSONからコンストラクトするため、このメソッドは呼ばれることは無い。
Expand All @@ -97,8 +86,7 @@ private SpeakerMeta() {
this.styles = new StyleMeta[0];
this.speakerUuid = "";
this.version = "";
this.speakerOrder = null;
this.styleOrder = new LinkedHashSet<>();
this.order = null;
}
}

Expand All @@ -115,9 +103,20 @@ public static class StyleMeta {
@Expose
public final int id;

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

private StyleMeta() {
this.name = "";
this.id = 0;
this.order = null;
}
}
}
Loading

0 comments on commit 4061678

Please sign in to comment.