ソフトウェア」カテゴリーアーカイブ

Open JTalk version1.09で音声合成

音声合成は2年ほど前に実験を行っていました。 Open JTalkとAquesTalkPiを比較し、聞きやすさの点でAquesTalkPiの方が良かったと記録しています。 久しぶりに確認すると、Open JTalkのバージョンは1.09となっていました。(以前の実験時は1.05) USBオーディオアダプタでサウンド機能の向上したRaspberryPiで、改めて実験してみました。

IMG_0390[1]

Raspberry Piにしゃべらせてみた を、参考にさせていただき、最新のOpen JTalk version1.09をインストールします。

・パッケージ管理 paco のインストール
# apt-get install paco

・hts_engine API version 1.10 のインストール
# wget http://sourceforge.net/projects/hts-engine/files/hts_engine%20API/hts_engine_API-1.10/hts_engine_API-1.10.tar.gz
# tar zxvf hts_engine_API-1.10.tar.gz


# cd hts_engine_API-1.10
hts_engine_API-1.10# ./configure
hts_engine_API-1.10# make
hts_engine_API-1.10# paco -lD "make install"
hts_engine_API-1.10# cd ..
#

・Open JTalk version 1.09 のインストール
# wget http://sourceforge.net/projects/open-jtalk/files/Open%20JTalk/open_jtalk-1.09/open_jtalk-1.09.tar.gz
# tar zxvf open_jtalk-1.09.tar.gz


# cd open_jtalk-1.09
open_jtalk-1.09# ./configure --with-charset=UTF-8
open_jtalk-1.09# make
open_jtalk-1.09# paco -lD "make install"
open_jtalk-1.09# cd ..
#

・パッケージ一覧の確認
# paco -a
# hts_engine_API-1.10 open_jtalk-1.09

・辞書ファイルの配置
# wget http://sourceforge.net/projects/open-jtalk/files/Dictionary/open_jtalk_dic-1.09/open_jtalk_dic_utf_8-1.09.tar.gz
# tar zxvf open_jtalk_dic_utf_8-1.09.tar.gz
# mkdir /usr/local/share/open_jtalk
# mv open_jtalk_dic_utf_8-1.09 /usr/local/share/open_jtalk/


・MMDAgent音声ファイルの配置
# wget http://sourceforge.net/projects/mmdagent/files/MMDAgent_Example/MMDAgent_Example-1.6/MMDAgent_Example-1.6.zip
# unzip MMDAgent_Example-1.6.zip
# mkdir /usr/local/share/hts_voice
# mv MMDAgent_Example-1.6/Voice/mei /usr/local/share/hts_voice/


・シェルスクリプトの作成(エディタで点線内のスクリプトファイルを作成)
nano /usr/local/bin/jsay

---------------------------------------------------------
#!/bin/sh
 
# 引数チェック
CMDNAME=`basename $0`
if [ $# -lt 1 ]; then
 echo "Usage: ${CMDNAME} [ text ]" 1>&2
 exit 1
fi
 
 
# 定数定義(出力ファイル名、辞書の場所、音声データの場所)
TMPFILE=`mktemp /tmp/tmp.XXXXXXXX.wav`
DIC=/usr/local/share/open_jtalk/open_jtalk_dic_utf_8-1.09/
VOICE=/usr/local/share/hts_voice/mei/mei_normal.htsvoice
 
 
# 音声データ生成
echo "$1" | open_jtalk \
-x ${DIC} \
-m ${VOICE} \
-ow ${TMPFILE} && \
 
 
# 生成した音声データを再生する
aplay --quiet ${TMPFILE}
 
 
# 生成した音声データを削除する
rm -f ${TMPFILE}
 
# 終了
exit 0
---------------------------------------------------------

・実行権限の付与
# chmod +x /usr/local/bin/jsay

・発声テスト
# jsay おはようございます。

以前のバージョンに比べ、発声がはっきりし、アクセントが改善されているように感じました。 「日本語の上手い外国人」といった印象で、テキストを確認しなければ聞き取れないということは、ほぼありません。 これは使えます。

簡単な、天気概況読み上げスクリプトを作成しました。

<?php
//weather.php 2016.3.27
//都市コード:http://weather.livedoor.com/forecast/rss/primary_area.xml
$city = "130010";
$url = "http://weather.livedoor.com/forecast/webservice/json/v1?city=$city";
$json = file_get_contents($url, true);
$json = json_decode($json, true);
$description = $json["description"]["text"]; //天気概況
$description = preg_replace('/】/','、',$description); //閉じ括弧を半濁点に変換
$description = preg_replace('/(【|\[|\]|\(|\)|〈|〉|「|」|[\.\?\-!&;:=~\r\n\s]+)/','',$description); //括弧と記号などを除去
echo $description."\n";
exec( "jsay 天気概況、".$description );
?>

php weather.php

で、最新の天気概況を読み上げます。 長い文章になると、変換時間もかかりますので、このあたりの改善が必要ですね。

 

参考にさせて頂いたサイト

Raspberry Piにしゃべらせてみた(OpenJTalk 1.08、.htsvoiceファイル対応)
http://raspi.seesaa.net/article/415482141.html

pacoでソースビルドをパッケージっぽく管理する
http://qiita.com/pasela/items/9c6cd7b9e477ed0501c8

 

 

pigpioでPWM制御する

PWMによる速度制御は「WiringPiでPWM制御する」で実験しましたが、致命的な問題により実用とはなりませんでした。 他に良い方法はないものかと探していると、pigpioというライブラリを発見! 実験してみました。

wave

pigpioは、サーボの制御やPWM信号の出力、またパルスの計測などの機能を提供するライブラリで、C言語やPython、コマンドラインなどから使用することができ、デーモンとしての動作も可能な為、非常に幅広く利用可能です。

インストール

wget abyz.co.uk/rpi/pigpio/pigpio.zip
unzip pigpio.zip
cd PIGPIO
make
make install

デーモンの起動

sudo pigpiod -a 1        #DMAメモリアロケーションモードをPMAPに指定

コマンドラインからの利用

pigs s 17 500          #GPIO17へ接続したサーボへ500ms幅のパルス出力 (500-2500)
pigs p 22 128         #GPIO22へデューティー比50%のPWM信号出力 (0-255)

C言語からの利用

ヘッダファイルとして pigpiod_if.h をインクルード
set_PWM_range(22, 255)                #GPIO22へ最大値を設定
set_PWM_dutycycle(22,128)          #GPIO22へデューティー比50%のPWM信号出力
gcc example.c -o example -lpigpiod_if -lpthread -lrt          #-lpigpiod_if を指定してコンパイル
コマンド一覧はこちらです

ダウンロードアーカイブにはサンプルプログラムも含まれていますので参考になります。

ServoBlasterとの共用は不具合を生じましたので、サーボ制御とPWM制御はpigpioに置き換えました。

今のところ問題なく動作していますので、このまま利用を継続し、他の機能についても検証してみたいと思います。

※2016.1.28追記

pigpioの使用方法についてコメントを頂きましたので、モーターの速度制御に使用しているコードを掲載いたします。

例えば、コンパイルしたmotor_pigpioを使用し、 sudo ./motor_pigpio f 128 と、実行することにより、50%の速度(デューティー比)で前進します。 この時、GPIO23,25に信号が出力されていますので、LEDを接続すると50%の明るさで点灯します。 128の数値を変えることでデューティー比が変化します。

//motor pigpio.c v1.00 20150810
//コンパイルは以下のコマンドを実行
//gcc motor_pigpio.c -o motor_pigpio -lpigpiod_if -lpthread -lrt

#include <stdio.h>
#include <pigpiod_if.h>


#define MOTOR1 22			// GPIO22
#define MOTOR2 23			// GPIO23
#define MOTOR3 24			// GPIO24
#define MOTOR4 25			// GPIO25
#define RANGE 255			//PWM最大値
#define LEFT_STR "l"
#define RIGHT_STR "r"
#define FWRD_STR "f"
#define BACK_STR "b"
#define STOP_STR "s"

int main(int argc, char **argv)
{
	int pwm,status;

	// 速度を設定
	if ( argc < 3 ){ pwm = 0; } else { pwm = atoi(argv[2]); } if ( pwm > RANGE ){ pwm = RANGE; }

	// pigpiod接続
	status = pigpio_start(0, 0);
	//if (status < 0){ return 1; }

	// softPWM設定
	set_PWM_range(MOTOR1, RANGE);
	set_PWM_range(MOTOR2, RANGE);
	set_PWM_range(MOTOR3, RANGE);
	set_PWM_range(MOTOR4, RANGE);

	//停止
	set_PWM_dutycycle(MOTOR1, 0);
	set_PWM_dutycycle(MOTOR4, 0);
	set_PWM_dutycycle(MOTOR2, 0);
	set_PWM_dutycycle(MOTOR3, 0);

	if ( strcmp( argv[1], FWRD_STR ) == 0 ){
		//前進
		set_PWM_dutycycle(MOTOR2,pwm);
		set_PWM_dutycycle(MOTOR4,pwm);
		return 0;
	} else if ( strcmp( argv[1], BACK_STR ) == 0 ){
		//後退
		set_PWM_dutycycle(MOTOR1,pwm);
		set_PWM_dutycycle(MOTOR3,pwm);
		return 0;
	} else if ( strcmp( argv[1], LEFT_STR ) == 0 ){
		//左ターン
		set_PWM_dutycycle(MOTOR1,pwm);
		set_PWM_dutycycle(MOTOR4,pwm);
		return 0;
	} else if ( strcmp( argv[1], RIGHT_STR ) == 0 ){
		//右ターン
		set_PWM_dutycycle(MOTOR2,pwm);
		set_PWM_dutycycle(MOTOR3,pwm);
		return 0;
	}

	//ブレーキ
	set_PWM_dutycycle(MOTOR1, RANGE);
	set_PWM_dutycycle(MOTOR4, RANGE);
	set_PWM_dutycycle(MOTOR2, RANGE);
	set_PWM_dutycycle(MOTOR3, RANGE);
	time_sleep(0.5);
	//停止
	set_PWM_dutycycle(MOTOR1, 0);
	set_PWM_dutycycle(MOTOR4, 0);
	set_PWM_dutycycle(MOTOR2, 0);
	set_PWM_dutycycle(MOTOR3, 0);

	return 0;
}

 

 

Raspbian最新カーネルでRTCの不具合が解消

RasPi2でリアルタイムクロック RTC-8564NB を使用する」で発生していたhwclockコマンドの不具合は、最新カーネル(4.0) へのアップデートにより、あっさり解消しました。 ハードウェアも、ショットキーバリアダイオードを介しバックアップ用ボタン電池を接続。 本来の使い方ができるようになると思っていましたが…。

clock

NTPサーバへのネットワークを切断した状態で起動すると、システムクロック・ハードウェアクロック共に初期化される現象に悩まされました。 アラームを設定しシャットダウンしてみると、指定した時間にアラーム出力は出ているので、どうやら、起動時に初期化されているようです。

hさんのサイトを参考にhwclock.shを修正してみましたが改善されず、さまざまなサービスや起動コマンドを停止しながら現象を確認しました。

結局、時刻合わせの為に有効となっているNTPデーモンが、上位サーバと通信できない時にシステムクロック・ハードウェアクロックを初期化していたことがわかりました。

NTPデーモンを停止し、代わりにNTPクライアントのntpdateをインストール。 1時間毎に実行する様cronへ設定し、システムクロック・ハードウェアクロックの問題は全面解決となりました。

OSインストール直後からのRTC設定手順です。

  1. /boot/config.txtへ
    dtoverlay=i2c-rtc,pcf8563 を追加
  2. /etc/modulesへ
    i2c-dev
    rtc-pcf8563 を追加
  3. /etc/rc.localへ
    hwclock -s を追加
  4. fake-hwclock
    ntp を無効化
  5. ntpdate をインストール
  6. cronへ
    ntpdate -v ntp.nict.jp を設定し定期実行

 

参考にさせていただいたサイト

Raspberry Piにリアルタイムクロックをインストールする

ntpdate – 日付と時刻をNTPサーバーと同期 – Linuxコマンド