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

add softalk #34

Merged
merged 1 commit into from
May 2, 2022
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ halberdはTTS(Text To Speech)ソフトウェアのファイルから字幕(srt,
- [VOICEROID](https://www.ah-soft.com/voiceroid/)
- [CoeFont](https://coefont.cloud/)
- [VOICEVOX](https://voicevox.hiroshiba.jp/)
- [SofTalk](https://w.atwiki.jp/softalk/)

halberdは上記TTSの権利を有する方々とは関係ない非公式のものになります

Expand Down
7 changes: 7 additions & 0 deletions docs/tips/softalk_tips.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# halberd with SofTalk

halberdをSofTalkで利用するための設定やtipsです

## テキスト書き出し設定

オプション ➡ 環境設定 ➡ 録音 ➡ 「録音時にテキストを自動的に保存する」に✅
8 changes: 7 additions & 1 deletion scripts/quick_halberd.bat
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
.\halberd.exe --version
set /p tts=TTS�̎�ނ���͂��Ă�������(1: voiceroid, 2: coefont)
set /p tts=TTS�̎�ނ���͂��Ă�������(1: voiceroid, 2: coefont, 3: voicevox, 4: softalk)
set tts=%tts%
if %tts% == 1 (
set tts="voiceroid"
)
if %tts% == 2 (
set tts="coefont"
)
if %tts% == 3 (
set tts="voicevox"
)
if %tts% == 4 (
set tts="softalk"
)

set input="%~f1"
if %input%=="" (
Expand Down
10 changes: 9 additions & 1 deletion scripts/quick_halberd.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/sh
echo "TTSの種類を入力してください(1: voiceroid, 2: coefont)"
echo "TTSの種類を入力してください(1: voiceroid, 2: coefont, 3: voicevox, 4: softalk)"
read tts;
if [ $tts = "1" ]
then
Expand All @@ -9,6 +9,14 @@ if [ $tts = "2" ]
then
tts="coefont"
fi
if [ $tts = "3" ]
then
tts="voicevox"
fi
if [ $tts = "4" ]
then
tts="softalk"
fi

echo "ディレクトリのパスを入力してください(1: 今のディレクトリで実行, それ以外: 入力)"
read input
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ fn main() {
Arg::new("TTS")
.help("set TTS")
.required(true)
.possible_values(&["voiceroid", "coefont", "voicevox"])
.possible_values(&["voiceroid", "coefont", "voicevox", "softalk"])
.index(1),
)
.arg(
Expand Down
24 changes: 22 additions & 2 deletions src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::fmt;
use std::fs;
use std::path::PathBuf;

use encoding_rs::{SHIFT_JIS, UTF_8};
use encoding_rs::{SHIFT_JIS, UTF_8, UTF_16LE};

#[derive(Debug)]
struct TextError(String);
Expand Down Expand Up @@ -58,6 +58,26 @@ pub fn generate_subtitle_from_same_name_txt_shift_jis(
Ok(text)
}

/// 引数pathと同じ名前のtxtファイル(UTF-16 LE))の中身を読む
/// * `path` - 対象のファイル
/// ok path = "01.wav" かつ 01.txtが存在する
pub fn generate_subtitle_from_same_name_txt_utf_16le(
path: PathBuf,
) -> Result<String, Box<dyn Error>> {
info!("Genarate subtitle from UTF_16LE txt file");
info!("input path: {}", &path.to_str().unwrap());
let mut text_path = path;
text_path.set_extension("txt");
info!("Open {}", &text_path.to_str().unwrap());
let rawtxt = match fs::read(text_path.as_path()) {
Ok(s) => s,
Err(_) => return Err(Box::new(TextError("can't open txt file".into()))),
};
let (res, _, _) = UTF_16LE.decode(&rawtxt);
let answer = res.into_owned();
Ok(answer)
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -125,7 +145,7 @@ mod tests {

#[test]
// 入力値が正常だったとき(txtファイルの中身がutf-8)
// 入力値がutf-8かつ英数字の時は文字化けしない
// 入力値がShift_JISかつ英数字の時は文字化けしない
fn normal_generate_subtitle_from_same_name_txt_shift_jis_unicode() {
let dir = tempdir().unwrap();
let input = dir.path().join("test.txt");
Expand Down
1 change: 1 addition & 0 deletions src/tts/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ pub mod profile;
pub mod service;
pub mod voiceroid;
pub mod voicevox;
pub mod softalk;
13 changes: 12 additions & 1 deletion src/tts/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::tts::coefont::CoeFont;
use crate::tts::profile;
use crate::tts::voiceroid::Voiceroid;
use crate::tts::voicevox::Voicevox;
use crate::tts::softalk::Softalk;

/// profile_nameから対応するTTSを選択する
/// * `profile_name` - TTSの名前
Expand All @@ -12,6 +13,7 @@ pub fn select_tts_talk(profile_name: &str) -> Result<Box<dyn profile::TTS>, &'st
"voiceroid" => Ok(Box::new(Voiceroid {})),
"coefont" => Ok(Box::new(CoeFont {})),
"voicevox" => Ok(Box::new(Voicevox {})),
"softalk" => Ok(Box::new(Softalk {})),
_ => Err("Didn't match profile name"),
}
}
Expand Down Expand Up @@ -39,14 +41,23 @@ mod tests {
}

#[test]
// 入力値が正常だったとき(入力値がcoefont)
// 入力値が正常だったとき(入力値がvoicevox)
fn normal_select_voicevox() {
let input = "voicevox";
let expected = "voicevox";
let result = select_tts_talk(input).unwrap();
assert_eq!(result.get_profile_name(), expected);
}

#[test]
// 入力値が正常だったとき(入力値がsoftalk)
fn normal_select_softalk() {
let input = "softalk";
let expected = "softalk";
let result = select_tts_talk(input).unwrap();
assert_eq!(result.get_profile_name(), expected);
}

#[test]
#[should_panic]
// 入力値が異常だったとき(入力値がどのTTSとも一致しない時)
Expand Down
31 changes: 31 additions & 0 deletions src/tts/softalk.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//! softalk関係のモジュール
use std::error::Error;
use std::fmt;
use std::path::PathBuf;

use crate::text;
use crate::tts;
use crate::wav;

pub struct Softalk {}

impl tts::profile::TTS for Softalk {
fn serif_generator(&self, path: PathBuf) -> Result<String, Box<dyn Error>> {
text::generate_subtitle_from_same_name_txt_utf_16le(path)
}
fn wave_time_generator(
&self,
reader: &hound::WavReader<std::io::BufReader<std::fs::File>>,
) -> f64 {
wav::calculate_wave_seconds(reader)
}
fn get_profile_name(&self) -> &'static str {
"softalk"
}
}

impl fmt::Display for Softalk {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "softalk")
}
}
1 change: 1 addition & 0 deletions tests/data/tts/softalk/01.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
���0c0O0�0W0f0D0c0f0m0
Binary file added tests/data/tts/softalk/01.wav
Binary file not shown.
1 change: 1 addition & 0 deletions tests/data/tts/softalk/02.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
���0�0�0`0\0
Binary file added tests/data/tts/softalk/02.wav
Binary file not shown.
15 changes: 15 additions & 0 deletions tests/softalk_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use std::boxed::Box;

use assert_cmd::Command;
use predicates::prelude::*;

#[test]
// 入力値が正常だったとき
fn normal_softalk() -> Result<(), Box<dyn std::error::Error>> {
let expected = "1\n00:00:00,000 --> 00:00:01,837\nゆっくりしていってね\n\n2\n00:00:01,838 --> 00:00:03,080\nダミーだぜ\n\n";

let mut cmd = Command::cargo_bin("halberd").unwrap();
let assert = cmd.arg("softalk").arg("tests/data/tts/softalk").assert();
assert.success().stdout(predicate::str::contains(expected));
Ok(())
}