気の向くままに辿るIT/ICT/IoT
IoT・電子工作

ラズベリーパイ 3 B+自作スマートスピーカーに音声メモ機能追加

ホーム前へ次へ
Raspberry Piって?

ラズベリーパイ 3 B+自作スマートスピーカーに音声メモ機能追加

ラズベリーパイ 3 B+自作スマートスピーカーに音声メモ機能追加

2019/05/28

 以前、作って運用しつつもブラッシュアップ中のRaspberry Pi 3 Model B+とJuliusOpen JTalkベースの自作スマートスピーカーがあります。

 主な機能は、

 尚、ラズパイ用ACアダプタを挿したスイッチ付きコンセントでのON/OFFとは別にラズパイ用boot/reboot/shutdown物理ボタン付き。

 音声認識にJuliusを使った自作スマートスピーカーに伝言とメモの機能を実装するにあたり、マイクとスピーカーを専有してしまうOSSやALSAからPulseAudioに移行しました。

 ちなみに便利なのでラズパイだけでなく、PC/Debianにも自作スマートスピーカー機能を搭載しています。

 自ずとモニタ付きとなるPC版スマートスピーカーには、PC及びラズパイ双方のスマートスピーカー機能のデスクトップアプリとしてPyQt5/Qt Designerによる操作パネルも作成しました。

音声メモ機能

[2019/05/30]
 現在、音声メモは、機能しません。(スクリプトでは可、スマートスピーカーでは不可)
 原因は特定済み、解決策模索中。

[2019/06/02]
 ALSA/PulseAudio使用で解決
 スクリプトの実行、Linuxパソコン版スマートスピーカー、ラズパイ版スマートスピーカーで機能することを確認済みです。

 今回は、音声メモ機能を追加してみました。

 想定としては、買い物リストとか、ふとした思いつきとか、基本、特定の1人が雑多に複数件登録する覚書的なメモです。

 再生時にそれらと混ざると煩わしいと思われるので伝言機能は別途つくることにします。

 ここでは、音声メモの登録、削除、再生は別々のスクリプトとし、メモ登録と削除には、Perlスクリプト、メモ再生には、シェルスクリプトを使うことにしました。

音声メモ登録用スクリプト

$ chmod +x add_memo.pl
$ cat add_memo.pl
#!/usr/bin/perl
 
use utf8;
use strict;
use warnings;
 
use 5.10.0;
use Time::Local;
 
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$year += 1900;
my $fname = "/path/to/voice/memo/$year$mon$mday$hour$min$sec.wav";
 
my $anounce="15秒以内でどうぞ";
my $saved_msg="メモを保存しました";
 
system("pactl set-source-volume alsa_input.usb-Generic_USB2.0_PC_CAMERA-02.analog-mono 82% &");
system("/path/to/jsay $anounce &");
sleep 3;
#system("/usr/bin/arecord -D plughw:1,0 $fname &");
system("arecord $fname &");
sleep 5;
system("pactl set-source-volume alsa_input.usb-Generic_USB2.0_PC_CAMERA-02.analog-mono 70% &");
system("pkill -f arecord");
system("vmplayer /usr/share/sounds/gnome/default/alerts/drip.ogg");
system("pkill -f mplayer");
system("/path/to/jsay $saved_msg &");
$

 現時点の自作スマートスピーカー仕様の場合、操作待ちさせるウェイクワードを発した後は、ウェイクワードなしで任意に設定できる有効時間内に「メモして」、「メモとって」などの音声操作をした時に呼ばれるスクリプトを想定しています。

 コールされると「15秒以内でどうぞ」の後、任意の音声を発して録音、ここでは、システムにあったポチャンのような効果音に続けて「メモを保存しました」というメッセージを以て録音完了とすることにしました。

 ファイル名には、秒まで含むlocaltime値を数値の並びとして使うことで重複することなく、いくつでもメモを保存できるようにしてみました。

 尤もあまりに数があると再生時、うざったいと思いますが。

[2019/06/02]
 本機能を使用可能にする解決策OSS(既存PC版スマートスピーカー)、ALSA(ラズパイ版)からALSA/PulseAudioへの変更に伴い、arecordの-D(デバイス指定)オプションが不要に。
 ちなみに音声操作と録音で音量を変更したかった為、解決策となるリンク先のpacmdによる事前設定に加え、PulseAudioのコマンドpactlで録音前後に音量調整する行を追加しました。

音声メモ削除用スクリプト

$ chmod +x del_memo.pl
$ cat del_memo.pl
#!/usr/bin/perl
 
use utf8;
use strict;
use warnings;
 
my $fpath="/path/to/voice/memo/*";
my $anounce="全てのメモを削除します";
my $deleted_msg="完了しました";
 
system("/path/to/jsay $anounce &");
sleep 5;
system("/bin/rm $fpath &");
sleep 1;
system("mplayer /usr/share/sounds/gnome/default/alerts/drip.ogg");
system("pkill -f mplayer");
system("/path/to/jsay $deleted_msg &");
$

 ウェイクワードを発した後、任意に設定できる有効時間内に「メモを削除して」、「メモを消して」などの音声操作をした時に呼ばれるスクリプトを想定しています。

 コールされると「全てのメモを削除します」の後、ここでは、システムにあったポチャンのような効果音に続けて「完了しました」というメッセージを以て削除完了とすることにしました。

音声メモ再生用スクリプト

$ chmod +x play_memo.sh
$ cat play_memo.sh
#!/bin/sh
 
fpath="/path/to/voice/memo/"
cnt=`ls $fpath | wc -l`
if [ $cnt -gt 0 ]
then
  anounce="メモは$cnt件です全てのメモを再生します"
  complete="メモは以上です"
 
  /path/to/jsay $anounce
 
  for fname in `ls $fpath`
  do
    /usr/bin/aplay $fpath$fname
  done
  /path/to/jsay $complete
else
  non_msg="保存されたメモはありません"
  /path/to/jsay $non_msg
fi
$

 前後しましたが、音声メモ再生用のスクリプトはこれです。

 ウェイクワードを発した後、任意に設定できる有効時間内に「メモを再生して」、「音声メモを再生して」、「音声メモ何かあったっけ」などの音声操作をした時に呼ばれるスクリプトを想定しています。

 コールされると録音済み音声メモがある場合、「メモは$cnt件です全てのメモを再生します」というメッセージの後、録音済みのメモが1件ずつ読み上げられ、「メモは以上です」というメッセージを以て読み上げ完了とすることにしました。

 録音した音声メモがない場合、「保存されたメモはありません」というメッセージが流れます。

機能は最小限

 日付をまたぐメモもあるだろうと思うと日付ごとにとか、今日とか昨日といった単位で読み上げるとか、やろうと思えばいろいろできるでしょう。

 が、複雑になりますし、そもそも、音声でそこまでできたところでスマートスピーカー操作と相まってかえって煩わしそうなので、このあたりが限界かと。

ラズパイスマートスピーカーへの反映

 /path/to/jsayについてや自作スマートスピーカーへの反映についての詳細は、冒頭の「自作スマートスピーカー」他、リンク先を参照してください。

ホーム前へ次へ