Skip to content

Commit

Permalink
Refactor (#37)
Browse files Browse the repository at this point in the history
* deref_buffer
Squashed commit of the following:

commit 0876813
Author: cm-ayf <[email protected]>
Date:   Fri Apr 5 23:27:53 2024 +0900

    rename macro

commit 1db87d8
Author: cm-ayf <[email protected]>
Date:   Fri Apr 5 23:27:36 2024 +0900

    fix type error

commit 5d7ed79
Author: cm-ayf <[email protected]>
Date:   Fri Apr 5 23:25:44 2024 +0900

    better use of derefs

commit cb8ea81
Author: cm-ayf <[email protected]>
Date:   Fri Apr 5 23:22:23 2024 +0900

    remove unnecessary .buffer.

commit 8f3af0e
Author: cm-ayf <[email protected]>
Date:   Fri Apr 5 23:11:49 2024 +0900

    migrate from buffer_index to deref_buffer

* refactor 1

* refactor 2

* refactor 3

* refactor 4

* from review

* attribute

* bump msrv
  • Loading branch information
cm-ayf authored May 11, 2024
1 parent 54a8dad commit 0fa36d5
Show file tree
Hide file tree
Showing 28 changed files with 735 additions and 599 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "jbonsai"
version = "0.1.0"
edition = "2021"

rust-version = "1.65.0"
rust-version = "1.75.0"

[features]
default = ["htsvoice"]
Expand Down
18 changes: 9 additions & 9 deletions benches/bonsais.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const MODEL_NITECH_ATR503: &str =
#[bench]
fn bonsai(bencher: &mut Bencher) {
// 盆栽,名詞,一般,*,*,*,*,盆栽,ボンサイ,ボンサイ,0/4,C2
let lines: Vec<String> = [
let lines = [
"xx^xx-sil+b=o/A:xx+xx+xx/B:xx-xx_xx/C:xx_xx+xx/D:xx+xx_xx/E:xx_xx!xx_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:4_4%0_xx_xx/H:xx_xx/I:xx-xx@xx+xx&xx-xx|xx+xx/J:1_4/K:1+1-4",
"xx^sil-b+o=N/A:-3+1+4/B:xx-xx_xx/C:02_xx+xx/D:xx+xx_xx/E:xx_xx!xx_xx-xx/F:4_4#0_xx@1_1|1_4/G:xx_xx%xx_xx_xx/H:xx_xx/I:1-4@1+1&1-1|1+4/J:xx_xx/K:1+1-4",
"sil^b-o+N=s/A:-3+1+4/B:xx-xx_xx/C:02_xx+xx/D:xx+xx_xx/E:xx_xx!xx_xx-xx/F:4_4#0_xx@1_1|1_4/G:xx_xx%xx_xx_xx/H:xx_xx/I:1-4@1+1&1-1|1+4/J:xx_xx/K:1+1-4",
Expand All @@ -20,9 +20,9 @@ fn bonsai(bencher: &mut Bencher) {
"N^s-a+i=sil/A:-1+3+2/B:xx-xx_xx/C:02_xx+xx/D:xx+xx_xx/E:xx_xx!xx_xx-xx/F:4_4#0_xx@1_1|1_4/G:xx_xx%xx_xx_xx/H:xx_xx/I:1-4@1+1&1-1|1+4/J:xx_xx/K:1+1-4",
"s^a-i+sil=xx/A:0+4+1/B:xx-xx_xx/C:02_xx+xx/D:xx+xx_xx/E:xx_xx!xx_xx-xx/F:4_4#0_xx@1_1|1_4/G:xx_xx%xx_xx_xx/H:xx_xx/I:1-4@1+1&1-1|1+4/J:xx_xx/K:1+1-4",
"a^i-sil+xx=xx/A:xx+xx+xx/B:xx-xx_xx/C:xx_xx+xx/D:xx+xx_xx/E:4_4!0_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:xx_xx%xx_xx_xx/H:1_4/I:xx-xx@xx+xx&xx-xx|xx+xx/J:xx_xx/K:1+1-4",
].iter().map(|l| l.to_string()).collect();
];

let engine = Engine::load(&[MODEL_NITECH_ATR503.to_string()]).unwrap();
let engine = Engine::load(&[MODEL_NITECH_ATR503]).unwrap();

bencher.iter(|| {
engine.synthesize_from_strings(&lines).unwrap();
Expand All @@ -37,7 +37,7 @@ fn is_bonsai(bencher: &mut Bencher) {
// です,助動詞,*,*,*,特殊・デス,基本形,です,デス,デス’,1/2,動詞%F1/形容詞%F2/名詞%F2@1,1
// か,助詞,副助詞/並立助詞/終助詞,*,*,*,*,か,カ,カ,0/1,動詞%F2/形容詞%F2/名詞%F1,1
// ?,記号,一般,*,*,*,*,?,?,?,0/0,*,0
let lines: Vec<String> = [
let lines = [
"xx^xx-sil+k=o/A:xx+xx+xx/B:xx-xx_xx/C:xx_xx+xx/D:xx+xx_xx/E:xx_xx!xx_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:3_3%0_xx_xx/H:xx_xx/I:xx-xx@xx+xx&xx-xx|xx+xx/J:2_10/K:1+2-10",
"xx^sil-k+o=r/A:-2+1+3/B:xx-xx_xx/C:04_xx+xx/D:24+xx_xx/E:xx_xx!xx_xx-xx/F:3_3#0_xx@1_2|1_10/G:7_5%1_xx_1/H:xx_xx/I:2-10@1+1&1-2|1+10/J:xx_xx/K:1+2-10",
"sil^k-o+r=e/A:-2+1+3/B:xx-xx_xx/C:04_xx+xx/D:24+xx_xx/E:xx_xx!xx_xx-xx/F:3_3#0_xx@1_2|1_10/G:7_5%1_xx_1/H:xx_xx/I:2-10@1+1&1-2|1+10/J:xx_xx/K:1+2-10",
Expand All @@ -58,9 +58,9 @@ fn is_bonsai(bencher: &mut Bencher) {
"s^U-k+a=sil/A:2+7+1/B:10-7_2/C:23_xx+xx/D:xx+xx_xx/E:3_3!0_xx-1/F:7_5#1_xx@2_1|4_7/G:xx_xx%xx_xx_xx/H:xx_xx/I:2-10@1+1&1-2|1+10/J:xx_xx/K:1+2-10",
"U^k-a+sil=xx/A:2+7+1/B:10-7_2/C:23_xx+xx/D:xx+xx_xx/E:3_3!0_xx-1/F:7_5#1_xx@2_1|4_7/G:xx_xx%xx_xx_xx/H:xx_xx/I:2-10@1+1&1-2|1+10/J:xx_xx/K:1+2-10",
"k^a-sil+xx=xx/A:xx+xx+xx/B:xx-xx_xx/C:xx_xx+xx/D:xx+xx_xx/E:7_5!1_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:xx_xx%xx_xx_xx/H:2_10/I:xx-xx@xx+xx&xx-xx|xx+xx/J:xx_xx/K:1+2-10",
].iter().map(|l| l.to_string()).collect();
];

let engine = Engine::load(&[MODEL_NITECH_ATR503.to_string()]).unwrap();
let engine = Engine::load(&[MODEL_NITECH_ATR503]).unwrap();

bencher.iter(|| {
engine.synthesize_from_strings(&lines).unwrap();
Expand All @@ -86,7 +86,7 @@ fn bonsai_letter(bencher: &mut Bencher) {
// あっ,動詞,非自立,*,*,五段・ラ行,連用タ接続,あっ,アッ,アッ,1/2,*,0
// た,助動詞,*,*,*,特殊・タ,基本形,た,タ,タ,0/1,動詞%F2@1/形容詞%F4@-2,1
// 。,記号,句点,*,*,*,*,。,、,、,0/0,*,0
let lines: Vec<String> = [
let lines = [
"xx^xx-sil+t=e/A:xx+xx+xx/B:xx-xx_xx/C:xx_xx+xx/D:xx+xx_xx/E:xx_xx!xx_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:4_4%0_xx_xx/H:xx_xx/I:xx-xx@xx+xx&xx-xx|xx+xx/J:6_24/K:1+6-24",
"xx^sil-t+e=g/A:-3+1+4/B:xx-xx_xx/C:02_xx+xx/D:23+xx_xx/E:xx_xx!xx_xx-xx/F:4_4#0_xx@1_6|1_24/G:6_2%0_xx_1/H:xx_xx/I:6-24@1+1&1-6|1+24/J:xx_xx/K:1+6-24",
"sil^t-e+g=a/A:-3+1+4/B:xx-xx_xx/C:02_xx+xx/D:23+xx_xx/E:xx_xx!xx_xx-xx/F:4_4#0_xx@1_6|1_24/G:6_2%0_xx_1/H:xx_xx/I:6-24@1+1&1-6|1+24/J:xx_xx/K:1+6-24",
Expand Down Expand Up @@ -130,9 +130,9 @@ fn bonsai_letter(bencher: &mut Bencher) {
"a^cl-t+a=sil/A:2+3+1/B:17-1_1/C:10_7+2/D:xx+xx_xx/E:3_1!0_xx-1/F:3_1#0_xx@6_1|22_3/G:xx_xx%xx_xx_xx/H:xx_xx/I:6-24@1+1&1-6|1+24/J:xx_xx/K:1+6-24",
"cl^t-a+sil=xx/A:2+3+1/B:17-1_1/C:10_7+2/D:xx+xx_xx/E:3_1!0_xx-1/F:3_1#0_xx@6_1|22_3/G:xx_xx%xx_xx_xx/H:xx_xx/I:6-24@1+1&1-6|1+24/J:xx_xx/K:1+6-24",
"t^a-sil+xx=xx/A:xx+xx+xx/B:xx-xx_xx/C:xx_xx+xx/D:xx+xx_xx/E:3_1!0_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:xx_xx%xx_xx_xx/H:6_24/I:xx-xx@xx+xx&xx-xx|xx+xx/J:xx_xx/K:1+6-24",
].iter().map(|l| l.to_string()).collect();
];

let engine = Engine::load(&[MODEL_NITECH_ATR503.to_string()]).unwrap();
let engine = Engine::load(&[MODEL_NITECH_ATR503]).unwrap();

bencher.iter(|| {
engine.synthesize_from_strings(&lines).unwrap();
Expand Down
14 changes: 7 additions & 7 deletions examples/genji/main.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
use jbonsai::{engine::Engine, model::interporation_weight::Weights};
use jbonsai::engine::Engine;

fn main() -> Result<(), Box<dyn std::error::Error>> {
let label_str = std::fs::read_to_string("examples/genji/genji.lab")?;

let lines: Vec<String> = label_str.lines().map(|s| s.to_string()).collect();
let mut engine = Engine::load(&vec![
let lines: Vec<_> = label_str.lines().collect();
let mut engine = Engine::load(&[
"models/tohoku-f01/tohoku-f01-sad.htsvoice",
"models/tohoku-f01/tohoku-f01-happy.htsvoice",
])?;
let iw = engine.condition.get_interporation_weight_mut();
iw.set_duration(Weights::new(&[0.5, 0.5])?)?;
iw.set_parameter(0, Weights::new(&[0.5, 0.5])?)?;
iw.set_parameter(1, Weights::new(&[0.5, 0.5])?)?;
iw.set_parameter(2, Weights::new(&[1.0, 0.0])?)?;
iw.set_duration(&[0.5, 0.5])?;
iw.set_parameter(0, &[0.5, 0.5])?;
iw.set_parameter(1, &[0.5, 0.5])?;
iw.set_parameter(2, &[1.0, 0.0])?;

let speech = engine.synthesize_from_strings(&lines)?;

Expand Down
8 changes: 4 additions & 4 deletions examples/is-bonsai/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use jbonsai::engine::Engine;

fn main() -> Result<(), Box<dyn std::error::Error>> {
let lines: Vec<String> = [
let lines = [
"xx^xx-sil+k=o/A:xx+xx+xx/B:xx-xx_xx/C:xx_xx+xx/D:xx+xx_xx/E:xx_xx!xx_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:3_3%0_xx_xx/H:xx_xx/I:xx-xx@xx+xx&xx-xx|xx+xx/J:2_10/K:1+2-10",
"xx^sil-k+o=r/A:-2+1+3/B:xx-xx_xx/C:04_xx+xx/D:24+xx_xx/E:xx_xx!xx_xx-xx/F:3_3#0_xx@1_2|1_10/G:7_5%1_xx_1/H:xx_xx/I:2-10@1+1&1-2|1+10/J:xx_xx/K:1+2-10",
"sil^k-o+r=e/A:-2+1+3/B:xx-xx_xx/C:04_xx+xx/D:24+xx_xx/E:xx_xx!xx_xx-xx/F:3_3#0_xx@1_2|1_10/G:7_5%1_xx_1/H:xx_xx/I:2-10@1+1&1-2|1+10/J:xx_xx/K:1+2-10",
Expand All @@ -22,10 +22,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
"s^U-k+a=sil/A:2+7+1/B:10-7_2/C:23_xx+xx/D:xx+xx_xx/E:3_3!0_xx-1/F:7_5#1_xx@2_1|4_7/G:xx_xx%xx_xx_xx/H:xx_xx/I:2-10@1+1&1-2|1+10/J:xx_xx/K:1+2-10",
"U^k-a+sil=xx/A:2+7+1/B:10-7_2/C:23_xx+xx/D:xx+xx_xx/E:3_3!0_xx-1/F:7_5#1_xx@2_1|4_7/G:xx_xx%xx_xx_xx/H:xx_xx/I:2-10@1+1&1-2|1+10/J:xx_xx/K:1+2-10",
"k^a-sil+xx=xx/A:xx+xx+xx/B:xx-xx_xx/C:xx_xx+xx/D:xx+xx_xx/E:7_5!1_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:xx_xx%xx_xx_xx/H:2_10/I:xx-xx@xx+xx&xx-xx|xx+xx/J:xx_xx/K:1+2-10",
].iter().map(|l| l.to_string()).collect();
];

let engine = Engine::load(&vec![
"models/hts_voice_nitech_jp_atr503_m001-1.05/nitech_jp_atr503_m001.htsvoice".to_string(),
let engine = Engine::load(&[
"models/hts_voice_nitech_jp_atr503_m001-1.05/nitech_jp_atr503_m001.htsvoice",
])?;
let speech = engine.synthesize_from_strings(&lines)?;

Expand Down
3 changes: 0 additions & 3 deletions src/constants.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
pub const MAX_F0: f64 = 20000.0;
pub const MIN_F0: f64 = 20.0;

/// log(MAX_F0) = log(20000.0)
pub const MAX_LF0: f64 = 9.903_487_552_536_127;
/// log(MIN_F0) = log(20.0)
Expand Down
75 changes: 38 additions & 37 deletions src/duration.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
use crate::model::Models;
use crate::model::MeanVari;

pub struct DurationEstimator;
pub struct DurationEstimator {
parameters: Vec<MeanVari>,
nstate: usize,
}

impl DurationEstimator {
pub fn create(&self, models: &Models, speed: f64) -> Vec<usize> {
let duration_params = models.duration();
pub fn new(duration: Vec<MeanVari>, nstate: usize) -> Self {
Self {
parameters: duration,
nstate,
}
}

pub fn create(&self, speed: f64) -> Vec<usize> {
// determine frame length
let mut duration = Self::estimate_duration(&duration_params, 0.0);
let mut duration = Self::estimate_duration(&self.parameters, 0.0);
if speed != 1.0 {
let length: usize = duration.iter().sum();
duration =
Self::estimate_duration_with_frame_length(&duration_params, length as f64 / speed);
Self::estimate_duration_with_frame_length(&self.parameters, length as f64 / speed);
}

duration
}

pub fn create_with_alignment(&self, models: &Models, times: &[(f64, f64)]) -> Vec<usize> {
let duration_params = models.duration();

pub fn create_with_alignment(&self, times: &[(f64, f64)]) -> Vec<usize> {
// determine state duration
let mut duration = vec![];
// use duration set by user
Expand All @@ -29,32 +35,32 @@ impl DurationEstimator {
for (i, (_start_frame, end_frame)) in times.iter().enumerate() {
if *end_frame >= 0.0 {
let curr_duration = Self::estimate_duration_with_frame_length(
&duration_params[next_state..state + models.nstate()],
&self.parameters[next_state..state + self.nstate],
end_frame - frame_count as f64,
);
frame_count += curr_duration.iter().sum::<usize>();
next_state = state + models.nstate();
next_state = state + self.nstate;
duration.extend_from_slice(&curr_duration);
} else if i + 1 == times.len() {
eprintln!("HTS_SStreamSet_create: The time of final label is not specified.");
Self::estimate_duration(&duration_params[next_state..state + models.nstate()], 0.0);
Self::estimate_duration(&self.parameters[next_state..state + self.nstate], 0.0);
}
state += models.nstate();
state += self.nstate;
}

duration
}

/// Estimate state duration
fn estimate_duration(duration_params: &[(f64, f64)], rho: f64) -> Vec<usize> {
fn estimate_duration(duration_params: &[MeanVari], rho: f64) -> Vec<usize> {
duration_params
.iter()
.map(|(mean, vari)| (mean + rho * vari).round().max(1.0) as usize)
.map(|MeanVari(mean, vari)| (mean + rho * vari).round().max(1.0) as usize)
.collect()
}
/// Estimate duration from state duration probability distribution and specified frame length
fn estimate_duration_with_frame_length(
duration_params: &[(f64, f64)],
duration_params: &[MeanVari],
frame_length: f64,
) -> Vec<usize> {
let size = duration_params.len();
Expand All @@ -68,19 +74,15 @@ impl DurationEstimator {
}

// RHO calculation
let (mean, vari) = duration_params
.iter()
.fold((0.0, 0.0), |(mean, vari), curr| {
(mean + curr.0, vari + curr.1)
});
let MeanVari(mean, vari) = duration_params.iter().sum();
let rho = (target_length as f64 - mean) / vari;

let mut duration = Self::estimate_duration(duration_params, rho);

// loop estimation
let mut sum: usize = duration.iter().sum();
let calculate_cost =
|d: usize, (mean, vari): (f64, f64)| (rho - (d as f64 - mean) / vari).abs();
|d: usize, MeanVari(mean, vari): MeanVari| (rho - (d as f64 - mean) / vari).abs();
while target_length != sum {
// search flexible state and modify its duration
if target_length > sum {
Expand Down Expand Up @@ -120,15 +122,16 @@ mod tests {
#[test]
fn without_alignment() {
let models = load_models();
let estimator = DurationEstimator::new(models.duration(), models.nstate());
assert_eq!(
DurationEstimator.create(&models, 1.0),
estimator.create(1.0),
[
8, 17, 14, 25, 15, 3, 4, 2, 2, 2, 2, 3, 3, 3, 3, 4, 3, 2, 2, 2, 3, 3, 6, 3, 2, 3,
3, 3, 3, 2, 2, 1, 3, 2, 14, 22, 14, 26, 38, 5
]
);
assert_eq!(
DurationEstimator.create(&models, 1.2),
estimator.create(1.2),
[
6, 12, 11, 19, 14, 3, 4, 2, 2, 2, 2, 3, 3, 3, 3, 4, 3, 2, 2, 2, 3, 3, 6, 3, 2, 3,
3, 3, 3, 2, 2, 1, 3, 2, 14, 18, 11, 16, 27, 4
Expand All @@ -139,20 +142,18 @@ mod tests {
#[test]
fn with_alignment() {
let models = load_models();
let estimator = DurationEstimator::new(models.duration(), models.nstate());
assert_eq!(
DurationEstimator.create_with_alignment(
&models,
&[
(0.0, 298.5),
(298.5, 334.5),
(334.5, 350.5),
(350.5, 362.5),
(362.5, 394.5),
(394.5, 416.5),
(416.5, 454.5),
(454.5, 606.5)
]
),
estimator.create_with_alignment(&[
(0.0, 298.5),
(298.5, 334.5),
(334.5, 350.5),
(350.5, 362.5),
(362.5, 394.5),
(394.5, 416.5),
(416.5, 454.5),
(454.5, 606.5)
]),
[
36, 86, 48, 102, 27, 7, 11, 6, 6, 6, 2, 4, 3, 4, 3, 3, 3, 2, 2, 2, 3, 6, 14, 6, 3,
4, 5, 6, 4, 3, 3, 1, 4, 4, 26, 28, 19, 42, 55, 8
Expand Down
Loading

0 comments on commit 0fa36d5

Please sign in to comment.