- 9VAeきゅうべえは、無料で動画素材がつくれるアプリです。
- 文字や矢印が動く モーショングラフィッ クソアプリです。アフターエフェクトに手が出ない人におすすめ。Youtube(Linux)、(Windows)
今回、9VAe Linux版にしゃべる機能を追加しました。
ダウンロード | 32bit Linux-x86 |
64bit Linux-x64 |
試し方 |
---|---|---|---|
Linux Mint Ubuntu Intel(x86/x64) |
Windows用 Linux起動USBの作り方 |
||
ラズベリーパイ | 他のOS版 9VAe |
- ZIPファイルをダウンロード(上をクリックしてから、[↓]ダウンロードボタン)
- Linux上で解凍
- フォルダの中の「9va-pi」を実行。9VAeが起動します。(Ubuntu、Mintでは動くはず。他のLinuxでは、9view(プレーヤー)しか起動しないものがあるようです)
- 9VAeきゅうべえの使い方はこちら。この記事の アニメGIF、動画はすべて 9VAe Linux版で作成しました。
- Ubuntu 64bitで OpenJtalk が apt-get できませんでした。Linux Mint は64bit でもOK。Ubuntu 64bit に OpenJTalkを入れる方法はこちら(Smile Engineering blog)
開発方針
- 9VAeは、1枚の絵に文字やイラストをいれて「ひとコマ」と設定するだけで、解説動画がつくれるのが特長です。
- ひとコマアニメは、1枚絵を書いただけで、書いた順番に文字や、図形が再生されます。文字が1文字ずつ順番にでてくる動画がすぐ作れます。
- この文字に「しゃべる」属性をつけるだけで、ゆっくり解説動画がつくれるようにします。
- しゃべる声は、男声と女声の2種類とし、2人が会話しながら解説する動画がつくれること。
- しゃべる声はユーザーがカスタマイズできるようにします。
わりきり仕様
- 9VAe は、どんな環境(Win / Mac / iOS / iPad / Android / Linux / Amazon Fire / ラズベリーパイ)でも同じように動きます。異なる OS 間で 互換性があります。これはすごいことですが、これを実現するために、移植が難しい仕様はいれないのがポイント。しゃべる機能は以下のようにしました。
- しゃべる声は、男声と女声の2種類
- 同時にしゃべることはない。
- 一度、しゃべりはじめると、最後まで、しゃべってから、次の発話がはじまる。
- しゃべる速さ、ピッチ、音量はエンジンの設定にまかせる。これらの調整は、今後の課題とする。
この割り切り仕様で、無料で使えるものをさがし、Linux では、音声合成エンジン Open JTalk を使うことにしました。
実装に必要な機能
- テキストをしゃべる
- 今しゃべっているかどうか調べる
- しゃべる音声をWAV ファイルに出力
- 発声の中断
各OSで上の機能をみたす関数を用意すれば移植できそうです。
現在、Linux、Windows、Android/Chromebook、Macintosh に移植できています。上の機能を実現方法を表にまとめました。
OS | 音声合成 | WAV作成 | 中断 | 発声中チェック |
---|---|---|---|---|
Linux(日本語) | OpenJTalk (外部ツール) |
-ow ファイルパス | kill(pid, SIGKILL); | waitpid(pid, &status, WNOHANG); |
Linux(英語) | eSpeak | --stdout > 音声ファイル | kill(pid, SIGKILL); | waitpid(pid, &status, WNOHANG); |
Windows(日本語) |
SofTalk (外部ツール) |
/PS:True /R:ファイルパス /W:しゃべる言葉 | mciSendString("stop",,,) | mciSendString("status",,,) |
Windows(英語) |
eSpeak (外部ツール) |
-w 音声ファイル | mciSendString("stop",,,) | mciSendString("status",,,) |
Android / Chromebook / Amazon Fire | tts = new TextToSpeech(this, this); | tts.synthesizeToFile(); | tts.stop(); | tts.speak()で発声追加。発声チェックはしない |
Macintosh | tts = [[NSSpeechSynthesizer alloc] init]; | [tts startSpeakingString:しゃべる言葉 toURL:ファイルパス]; | [tts stopSpeaking]; | [tts isSpeaking]; |
iOS / iPad | tts = [[AVSpeechSynthesizer alloc] init]; | [tts writeUtterance:utterance toBufferCallback:]; | [tts stopSpeaking]; | [tts isSpeaking]; |
音声合成 Open JTalk
参考文献:Raspberry piで日本語音声合成(Open JTalk)を試してみる。
インストール方法(Linux)
$ sudo apt-get install open-jtalk
$ sudo apt-get install open-jtalk-mecab-naist-jdic
$ sudo apt-get install hts-voice-nitech-jp-atr503-m001
これで、男声でしゃべれるようになります。
コマンド入力するとき、数文字入力して、TABキーを押せば楽に入力できます。
女声のインストール方法
女性の声は Meiちゃんがよく使われているようです。
$ wget https://sourceforge.net/projects/mmdagent/files/MMDAgent_Example/MMDAgent_Example-1.6/MMDAgent_Example-1.6.zip/download -O MMDAgent_Example-1.6.zip
$ unzip MMDAgent_Example-1.6.zip MMDAgent_Example-1.6/Voice/*
$ sudo cp -r MMDAgent_Example-1.6/Voice/mei/ /usr/share/hts-voice
音声コマンド
上のインストールを行ったあと、ターミナルで以下の命令をいれればしゃべりました。
- テキストをしゃべる
$ echo 12345 | open_jtalk -m /usr/share/hts-voice/nitech-jp-atr503-m001/nitech_jp_atr503_m001.htsvoice -x /var/lib/mecab/dic/open-jtalk/naist-jdic -ow test.wav
$ aplay test.wav
これで「いちまんにせんさんびゃくよんじゅうご」としゃべりました。12345の部分に UTF8 の文字をいれれば自由にしゃべります。
- -ow 出力ファイル名 で、WAVファイルに出力できるようです。
- aplay が WAVファイルを発声する命令です。-q オプションで表示が消えます。
参考文献:萌え声を探せ!Open JTalkのパラメータをいろいろ変化させてみた!
Linuxでの実装
- 発声の中断、しゃべっているかどうかのチェック、しゃべり方の調整が行えるようにするために、「Open JTalk で WAV 作成する男声命令」「女声命令」を用意し、まず、WAVを作成することにしました。
#!/bin/sh
echo "$1" | open_jtalk -jm 1.2 -m /usr/share/hts-voice/nitech-jp-atr503-m001/nitech_jp_atr503_m001.htsvoice -x /var/lib/mecab/dic/open-jtalk/naist-jdic -ow /tmp/#9va_talk.wav && mv /tmp/#9va_talk.wav /tmp/9va_talk.wav
#!/bin/sh
echo "$1" | open_jtalk -m /usr/share/hts-voice/mei/mei_normal.htsvoice -x /var/lib/mecab/dic/open-jtalk/naist-jdic -ow /tmp/#9va_talk.wav && mv /tmp/#9va_talk.wav /tmp/9va_talk.wav
まず、#9va_talk.wav というファイル名でWAVを作成し、出力後に 9va_talk.wavという名前に変更しています。名前固定がいまいちですが、わりきり仕様ということで・・・
この命令を読みだす部分は以下のようになってます。
作成した WAVファイルの再生は、Linuxでは「aplay」命令をつかっています。
#define TEXT_MAX_BUF 1024
#define aTALK_WAV_FILE "/tmp/9va_talk.wav" //Waveファイル
#define aTALK_WAV_CMD "aplay" //Waveを再生する命令
typedef struct {
pid_t pidMakeWav;
pthread_t thrMakeWav;
char prgMakeWav[600]; //jtalk を呼び出す Shell
char utf8Talk[TEXT_MAX_BUF]; //しゃべる言葉
pid_t pidTalk;
pthread_t thrTalk;
char prgTalk[100]; //Wav再生
} AcGbl;
Wave 作成
static void *thread_MakeWav(void *ax){
AcGbl *axx = (AcGbl *)ax; char *cmd = axx->prgMakeWav;
pid_t pid = fork(); int status;
if(pid==0){
execlp(cmd , cmd, axx->utf8Talk, NULL);
exit(0);
}
waitpid(pid, &status, 0);
axx->pidMakeWav =pid;
}
Wave再生
static void *thread_Talk(void *ax){
AcGbl *axx = (AcGbl *)ax; char *cmd = aTALK_WAV_CMD;
pid_t pid = fork();
if(pid==0){
execlp(cmd , cmd, "-q", aTALK_WAV_FILE, NULL);
exit(0);
}
axx->pidTalk =pid;
}
- fork することで、バックグランドで音を鳴らしつづけます。再生が終わるとプロセスが終了するので、それを検出することで、しゃべり終わったかどうかをチェックします。
しゃべっているかどうかチェック
int isTalking(AcGbl *axx)
{
pid_t pid = axx->pidTalk; int status;
pid = waitpid(pid, &status, WNOHANG);
return pid==0; //再生中
}
発声の中断
void stopTalk(AcGbl *axx)
{
int status;
if(isTalking(axx)){
kill(axx->pidTalk, SIGKILL); wait(&status);
pthread_cancel(axx->thrTalk);
pthread_join(axx->thrTalk, NULL);
}
}
しゃべるテスト
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <stddef.h> //NULL
#include <sys/types.h> //fork
#include <sys/unistd.h> //fork
#include <sys/wait.h>
#include <sys/signal.h>
void main(int argc, char *argv[])
{
AcGbl ag; memset(&ag,0,sizeof(&ag));
puts("Start");
strncpy(ag.prgMakeWav, "/sh命令を置いた場所/talkman_jp.sh",sizeof(ag.prgMakeWav));//男声
//strncpy(ag.prgMakeWav, "/sh命令を置いた場所/talkwoman_jp.sh",sizeof(ag.prgMakeWav));//女声
//しゃべらせたい言葉、UTF8 でいれる
strncpy(ag.utf8Talk, "1234567",sizeof(ag.utf8Talk));
puts("Make wave");
thread_MakeWav(&ag); //WAVの作成
puts("Talk 1");
thread_Talk(&ag);
for(;isTalking(&ag);) ;//しゃべり終わるのを待つ
puts("Talk 2");
thread_Talk(&ag);
sleep(2); //2秒後に終了
puts("Break");
stopTalk(&ag);
}
テストプログラムのコンパイルと実行
$ gcc -pthread test.c
$ ./a.out
- まず「ひゃくにじゅうさんまんよんせんごひゃくろくじゅうなな」としゃべります。
- 喋り終わるのをまってから、もう一度しゃべります。こんどは2秒あとに中断して終了します
9VAeでの文字入力としゃべる設定
- Open JTalk がインストールされていなければ、しゃべりません。9VAe Linux版でしゃべる機能を試すには、Open JTalk をインストールしてください。
- Linux Mint. Ubuntu32bitは上の方法でインストールできました。Ubuntu 64bit の場合はこちら(Smile Engineering blog)
文字入力としゃべる設定
9VAeで文字を入力したあと、文字の選択枠の中心の「+」をクリックすると表示されるメニューに「しゃべる」「コメント」の2項目を追加しました。「コメント」文字は表示されない文字で、画面にないせりふをしゃべるときに使います。
しゃべる属性をつけると、男声でしゃべるようになります。
しゃべるを解除するには、文字パレット(次の項目)の右端のボタンをつかいます。次の項目参照
女性の設定
右側の文字パレットの配置属性メニューに「男がしゃべる」「女がしゃべる」を追加しました。文字を選んで(複数も可能)「女がしゃべる」にすると女声になります。ただし女声をインストールしていなければ男声でしゃべります。
- もう一度同じ設定をクリックすると「しゃべる」属性が解除されます。
しゃべる順序、しゃべる時間の調整
ページの時間を「ひとコマ」に設定すると、しゃべる音声の長さを計測し、ページの時間を自動設定します。
しゃべる順番は、つぎのようになります。
- しゃべる設定されたコメント文字があれば、重なり順序の下からしゃべります。
- しゃべる設定された文字を重なり順序の下からしゃべります。
- 前の声がしゃべり終わるまで、つぎの文字をしゃべりません。
- 文字はページが切り替わっても最後までしゃべります。しゃべりはじめていない文字は、次のページにうつると読み飛ばされます。
- 再生中止ボタンを押すと、しゃべるのをやめます。
動画作成
- ファイルメニュー>「動画出力」で、上のしゃべるルールに従って、しゃべる動画が出力されます。
-
動画出力するには ffmpeg が必要です。インストールはこちら。Youtube解説
以下の動画は、この方法で作成しました。
マルチOS対応の仕組み
- 9VAeきゅうべえは、Win/Mac/Android/iOS で動きます。ソースは9割が C言語で共通化されています。しかし、文字入力、描画、しゃべるなどは、OSごとに処理が異なり、各OS用のルーチンに差し替えています。
- アニメ再生などの時間管理は、C の共通ソースにあり、CからOSルーチンをどう呼び出すかが問題となります。各OS処理を C から呼び出せるか、以下のようになっています。
OS | OS側 | C から直接呼べるか |
---|---|---|
Windows | Win32 C++ | 〇 |
Linux | GTX C++ | 〇 |
Android | Java | 〇(JNI) |
Mac | Objective-C | × |
iOS/iPad | Objective-C | × |
- C から直接呼び出せない場合は、非同期処理になります。例えば、文字をしゃべらせる時間がすぐにはわからないので、結果がわかってから処理を続ける仕組みが必要になります。
- C からOSの関数を呼び出せても、処理結果がすぐには出ない処理もあります(文字入力など)。
OSによって非同期処理が異なるため、しゃべる処理の移植はかなり複雑になりました。