Raspberry Pi、ESP8266/ESP-WROOM-02/ESP-WROOM-32/ESP32、音声認識エンジンJulius、デフォルトでは日本語の音声合成Open JTalkでスマートスピーカーを自作してみるページ。
内蔵時計、天気APIとも連携し、日付、時刻、今日の天気、明日の天気、明日の(最高/最低)気温も日本語で聞けば教えてくれます。
また、スマホやタブレット、パソコンなどからWiFi操作で壁や家具越しにも操作可能なESPモジュールによる自作IR・赤外線リモコンでリモコン対応家電や自作スマートプラグ(スマートコンセント)に挿した非リモコン家電を日本語の音声でWiFi越しにON/OFF操作(スマートリモコン化)できます。
今のところ、これくらいですが、思いついたものは、どんどん機能追加していく予定のこのスマートスピーカーは、公開されている情報の組み合わせで比較的簡単にできました。
Amazon EchoにおけるAlexaの日本語版発売が、2017年11月と考えると、そういう意味では、そこそこ最新っぽい(AI使ってないけど?ん?Juliusで使ってるHMM/Hidden Markov Model/隠れマルコフモデルもAI?)。
自作IoTガジェットで非IoTな自宅がスマートホームに...。
一方、ESPチップ・モジュールでも設定次第で外からも操作可能ですし、esp8266-alexa-wemo-emulatorを作って下さった強者もおり、おかげでAlexa定型アクションでも使えますが、ここでは、定型アクションも備えるスマートスピーカーを自作します。
さて、自作スマートスピーカーのメインとなるハードウェアは、Raspberry Pi。
Raspberry Piのモデルに合わせた出力のUSB充電器、microSDカードやUSBメモリ、microUSB-USB Aケーブルあたりは必要。
また、スマートスピーカーと言えば、マイクとスピーカーは必須。
どんなものでも良いですが、ただ、ラズパイにオーディオジャックは一つしかなく、スピーカーは、オーディオプラグのみか、USB+オーディオプラグのものしかないでしょうから、自ずとマイクはUSB接続のものを選ぶことになるでしょう。
あ、USBサウンドアダプタを使えば、マイクとスピーカーがどっちもオーディオジャック出しでも同時にUSBに変換することもできるかもしれませんが。
ラズパイにはマイク入力端子がないとのことで後述のようにラズパイで使う限りにおいては、少なくともマイクはUSB接続のものを調達すべきな模様。
スマートスピーカーの自由度を上げるなら有線より無線、ラズパイ3B/3B+は内蔵してるけど、ラズパイ2 Bなら無線LANドングル、有線環境はあるけど無線環境自体ないなら有線ルータにつないでアクセスポイントにする用の無線LANルータも。
あると便利なのは、個別スイッチ付き電源タップとか、電圧・電流チェッカーあたり。
USB充電器、USBケーブル、microSDカードやUSBメモリなどラズパイ一式の他、マイクとスピーカーを用意、これらが使える状態にあること。
OSもインストール済みの利用可能なラズパイにホスト名.localでアクセスできるようにOSに応じてAvahiかBonjour、音声認識用にJulius、音声合成用にOpen JTalkをインストールや必要に応じてgit cloneかダウンロード・展開し、動作確認してあること。
と言っても自身は、現在、サーバに使っているもの以外にラズパイを持っていないので、とりあえず、パソコン上でRaspbianのベースでもあるDebian(Linux)で代用しましたが。(ラズパイを使う場合の注意点)
また、スクリプトやプログラム言語は、何でも良いですが、ここでは、シェルスクリプトの他、PerlスクリプトとPython(2.7/3.6)スクリプトを使ったので、これらがインストールされていること。
参考までに自身が今回使用したOSは、Debian Stretch amd64、Arduino IDEのバージョンは、1.8.7。
基本、ラズパイ一式の価格プラスアルファといった価格構成になると思われ、持ち運びを考慮するとWiFi必須、処理速度からしてRaspberry Pi 2B/3B/3B+が無難、2B+WiFiドングルか、WiFi内蔵3B/3B+か、何れにするにしてもラズパイケース、USB充電器、microSDカードかUSBメモリ、USBケーブル等々一式でAmazon相場で1万円前後かと。
今回、映像関連機能をも見据えて?マイク内蔵USBカメラを使いましたが、マイク、スピーカー、その他諸々、Amazon&Amazonマーケットプレイス&100円ショップ相場で一部電子部品などは単価割したとして約2000〜3000円程度?
締めて1万2千〜1万3千円前後くらいかと。
Aliexpress相場だとこれの7割くらい〜半額程度といったところでしょうか。
あんまり深く考えていませんが、一から買い揃えるとなると、量産された市販のスマートスピーカーを買ったほうが安いかも?とも思いましたが、そうでもなく、いろいろメリットもありそうです。
Open JTalkは、日本語を標準とするテキストを音声に変換し、読み上げてくれるソフトウェアです。
デフォルトで漢字、ひらがな、カタカナ、アルファベット、算用数字、漢数字、また、日付時刻など意味のある漢字数字混じりの並びの文は、それに合わせて相応に読んでくれます。
より最新に近いLinuxのリポジトリや、公式サイトなどから、より最新のOpen JTalkパッケージを取得した場合、冒頭や後段のリンク先に書いた通り、インストールや展開するだけで簡単に試してみることができます。
より具体的には、端末(コンソール・ターミナル)上で必要に応じたオプション付きのopen_jtalkコマンドにテキストをechoしてパイプ経由で渡したり、テキストファイルをcatやリダイレクトしたりするだけで日本語で音読してくれます(読み上げてくれます)。
Open JTalkに関しては、後述のPerlスクリプトから利用できるようにスクリプトを作成、実行権限を与えておきます。
スクリプトは何でも良いですが、ここでは、Raspberry Piを使ってスマホ・音声で家電を制御するのbashスクリプトを使わせて頂きました(自身はシェバンを#!/bin/shとしました)。
ただ、中間にあったオプションがことごとくエラーとなり、調べても今ひとつよくわからなかったため、省きました。
また、メイさんの音声ファイルの格納ディレクトリ構成が変わったようなので修正したついでに、声色は、normalではなく、happyなメイさん(mei_happy.htsvoice)にお願いすることにしました。
これで入力された単語や文章を元気はつらつなメイさんが、しゃべってくれるようになります。
Juliusは、標準では、日本語の音声をテキストに変換してくれるソフトウェア。
Juliusは、より最新に近いLinuxのリポジトリや、公式サイトなどから、より最新のJuliusパッケージを取得した場合、冒頭や後段のリンク先に書いた通り、インストールするだけで簡単に使ってみることができます。
端末(コンソール・ターミナル)上で必要に応じたオプション付き(例えば、最も簡潔なものの1つは、dictation kitのディレクトリに移動し、[julius -C config_file]のようにする)のjuliusコマンドにモジュールモードでの起動を指定する-moduleオプションを付けて([julius -C config_file -module])サーバとして待機させておきます。
ただ、そのconfig_file内で指定する辞書については、標準のものも使えますが、今回のようなリモコン操作など使いみち(使う言葉)が限定されればされるほど自作した方が格段に認識率があがるので、自身の用途に応じて作成する必要があるでしょう。
今回は、これまた、先のjsayスクリプトでお世話になったリンク先から拝借したものをベースに追加する恰好でこんな辞書を作ってみました。
dictation kitの場合、おおまかに最小限で言うと命令に当たる日本語のフレーズと、ちょっとした作法に基づいて、これの読みとなるアルファベットの並びを一行ずつ書いたファイルのエンコードをeuc-jpに変換したもの。
「ちょっとした作法」というのは、無音部分を表わすらしき、<sil>行は、とりあえず、そのまま書いておく、少なくとも母音と子音との間は半角スペースで区切る、大文字の[N]は[ん]を表わす、[:](コロン)は、音をのばすときに使うなど(半角スペース区切りは、先の決まりごと以外の部分でも使え、ここでは基本半角スペース区切りを多用しています)。
ここでは、3列ありますが、2列めは、1列めやこれに準ずる音声が発せられたとき、Juliusがテキスト表示する際の文字列となり、後述のPerlスクリプトの条件分岐では、この2列めのフレーズで判定しています。
ちなみに「冷房」については、後述のPerlスクリプトの方で冷房の条件分岐を書き忘れ、認識しないな...というボケをかまして、ちょっとハマり、[r e i b o u]、[r e: b o:]はどっちでも、良かったはずですが、認識しないのと勘違い...[r e I]としたら、[I]がエラーではじかれたりしつつ、書き忘れに気づき、その時書いてあった[r e: b o:]とすることにした経緯があります。
ただ、詳細は割愛しますが、別途スクリプトで判定する文字列をどうしたらよいのかはさておき、辞書としては、grammer kitで.grammarと.vocaファイルを作成、mkdfa.plで変換し、.dfa/.dict/.termファイルを作成、併用する方が、「今日」とか「明日」とか、「つけて」「けして」など重複するものをまとめられるため、スマートだし、こうした用途の場合、本来の使い分けとして想定されているのは、この方法である模様。
先で例示した辞書は、エンコーディングがUTF-8ですが、このようにeuc-jpにエンコード・変換したファイルを辞書として指定しないとエラーになったり、原因不明と無駄にあたふたする羽目になったりします。
ちなみにgrammar kitの方の.vocaは、SJISだったりして、ちょっと、ややこしい...。
例えば、dictation kitのconfig_fileにおいて辞書は、-wオプション付きで指定します。
この中でmysmartspeaker.eucjp以外の言語モデルや音響モデルは、Julius標準のものを使っているだけ。
このように実行した状態で自マシン上の他の端末(や設定によっては他のマシン上の端末)から相応の手順を書いたスクリプトでアクセスし、音声を発すると他の端末やマシンに結果をテキストで返してくれます(というのが、モジュールモード)。
オウム返しでは、芸がない(ボイスチェンジャーか遠方に音声を届けるくらいしか使いみちを思いつかない)が、発声した言葉に応答してくれる(そのようにスクリプトに書くことができる)となると格段に発想が広がる...いや、そうでもない...か?
今回、Perlを使った、そのスクリプトがこれ(voicereceive.pl)でベースは、bashスクリプトjsayやJulius辞書でもお世話になったリンク先のPerlスクリプトを、ESPモジュールへHTTPアクセスするにあたっては、Perl/Webアクセスから拝借しました。
また、天気APIから情報を得るスクリプトについては、livedoorの天気予報API『Weather Hacks』を使ったというPythonで書かれたtalk_weather.pyをhttp://raspi.seesaa.net/article/415530289.htmlから拝借。
入力に応じた分岐条件を追記・編集してもよかったのかもしれませんが、Python初心者の自身は、用途ごとにスクリプトファイルを分割し、ベースと成るPerlスクリプトから、それらPythonスクリプトを直接呼び出す方法をとりました。
このpythonスクリプト内では、奇しくも発話用にjsayという同じ名前のスクリプトを指定していますが、登録済み実行パスに存在するコマンドとして書いてあるようなので、そうでない場合は、環境に応じてjsayスクリプトのパスを合わせておく必要があります。
日付と時刻は、天気予報APIからも取得できることを後で知ることになりますが、先にPerlでは、最も古い部類と思われるlocaltime()関数から取得する方法をとっていたため、その値を加工して使いました。
が、スクリプト内でlocaltime()を使ったところで、これだと実行時から更新されない為、Web APIから取得するか、オリジナルスクリプトで対応する必要がありました。
ここでは、日付、曜日、時間用にdate、awk、sedとjsayスクリプトを使ったshellスクリプトをそれぞれ作って自作スマートスピーカー用perlスクリプトvoicereceive.plに反映させることにしました。
ただし、時・分・秒共にちょうど(00)の際は、読み飛ばされるので、気になる場合は、別途処理を要します。
今回作った一連の回路では、家電の操作・制御をより遠くから行なうことができるようにWiFiを介して操作するものを想定し、実際、そのようにしました。
ベースとさせて頂いたPerlスクリプトでは、音声に反応してラズパイから赤外線信号が届く範囲で操作する前提で直接信号出力するように書かれています。
一方、今回は、プログラムを書き込むことができるWiFiモジュールであるESP8266/ESP32にリモコンとなる赤外線LEDを回路として組んであるため(というほどでもないが)、壁や家具・家電、何ならフロアを越えてもWiFi信号が届く範囲で利用可能であり、このPerlスクリプトからは、WebサーバでもあるESPの特定のパスにアクセスさせることにしました(そうすることでESP側で赤外線信号を発信するようにしました)。
このサンプルスクリプトのリモコン操作に関しては、テレビのON/OFFの部分しか編集しておらず、他の分岐も一部追記はしたものの、発信信号を含めたコピペでしかありません。
尚、Perlスクリプト冒頭でJuliusのアクセス先を'localhost'としたので今回は、自マシンの他の端末からモジュールモードで起動したJuliusにアクセスすることになります。
とは言え、コンセント接続、電源ONボタンでラズパイのOSが起動、マイクは構成ファイル上で環境変数に登録するなどしておき、無線LANに接続、cron登録されたJulius、Perlスクリプトを順次起動、準備完了LED点灯...といった完成品らしきものを作る場合でも自己完結させるなら'localhost'でよいでしょう。
思うところあって応答スクリプトをPerlからPython(3.x)に書き換え・変更しました。
まだ、思うところについては実装していませんが。
たまにですが、意図せず、あれこれ立て続けに複数の応答があって過剰認識気味な時がある気がするので、これをPCで、ラズパイスマートスピーカーの方は、従来のPerlで様子を見ることにします。
尚、Perlスクリプトではそうしたことはありませんでしたが、Pythonスクリプトだと、なぜか、以下のような対処が必要でした。
YouTube、Internet-radio.comなど音楽ストリーミングやサイマルラジオに関しては、応答スクリプト内でmplayerなどを使って直接か、スクリプトを介してかに関わらず、再生直前に(3秒ジャストだと足りない)スリープをかます必要が。
ABCワールドニュースやBBCワールドニュースなどニュース系は大丈夫でした。
全て直前にpkillなど各種停止コマンド、ローカルサーバ用のumountなどを仕込んだスクリプト実行との絡みかと思われます。
当該スクリプト行をコメントアウトするとスリープを入れる必要もなく音楽系のストリーミング再生もされるので。
過剰認識気味、思うところ、更にABCワールドニュースやBBCワールドニュースでもスリープ必要だったので、この3点は勘違いでした。
time.sleep()に変更はしませんでしたが、よく見たら、そもそもradikoも1秒ではありますが、スリープ入れてましたね。
尚、if文評価で'値' == 変数となっているのは、Perlのwhen文からPythonのif文にスクリプトを一括変換した際の名残です(またの名を手抜きとも言う)。
ラズパイスマートスピーカー機能が起動しなくなり、調べてみると、なぜか、Perlの応答スクリプトでuseやrequireしているモジュールがことごとく、"did not return a true value at"となる、末尾に1;は入っている、他の原因を探すのも億劫。
よって深追いせず、ラズパイスマートスピーカーの応答スクリプトもPerlからPython(3.x)に書き換えたものに変更することにしました。
ESP8266/ESP32などのESPボードをWebSocketサーバ、pip/pip3(Python2.x/Python3)でインストールしたwebsocket-client-py/websocket-client-py3ライブラリを使ったPythonスクリプトをクライアントとし、スマートスピーカーとしてのみならず、パソコンとして使っているものからの検証なども含むRaspberry Piから操作をする場合の注意事項について。
websocket-client-py/websocket-client-py3には、スクリプトの生存期間としてのShort-lived connectionとLong-lived connectionという2つのバージョンが紹介されていますが、単にshort/longの差のみならず、使い分けが必要なケースがあったよという話です。
というか、ライブラリ云々ではなく、PCに入れた自作スマートスピーカー機能からの音声操作やスクリプト実行ではショートバージョンでも100発100中で問題なく、スマートスピーカーとして、また、サブパソコンとして使っているRaspberry Pi(ちなみに何れも3 B+)に共通するのでラズパイに起因するようです。
ロングバージョンを使った方が良い(安定して操作できる)のは、どうやら、Rapsberry Piから操作するESP32ボードの全てと一部のESP8266ボードが対象となると思われます。
ESP8266ボードについては、予想の域を出ませんが、スマートスピーカーから一定以上の距離(ラズパイのWiFiチップだと無線が微妙に届きにくいところ)にあるものかなと思っていますが、あれ?ESP32も全てじゃなくて同じ原因かも?
ラズパイスマートスピーカーからショートバージョンでもいけてるのは、ダイニングキッチンにあるスマートスピーカー近くにあるESP8266ボード1つ、ロングバージョンでないといけないESP8266ボード1つとESP32ボード3つのこれら計4つは、別部屋に割とまとまって設置してあるので...。
とは言え、ちなみに同じスマートスピーカー機能を入れてあるメインPCも同じ部屋内の近くにあるものの、ダイニングキッチンにあるラズパイスマートスピーカー近くにあるESP8266も余裕で操作できている為、やはり、ラズパイのWiFiチップは、電波キャッチするの苦手なのかも!?
何れにせよ、この時、ここでスマートスピーカーの応答用として使用しているスクリプトvoicereceive.plにもちょっとした工夫が必要となります(他にも方法はあるかもしれませんが)。
具体的に言うと、これらでショートバージョンを使うとスクリプト実行段階で下手をすると数%成功するか否かというほどに成功率が格段に下がり、とても実用的とは言えない状態になり、ロングバージョンだと確実に操作できるので後者を使うのが賢明です(ここに気づくに至るまでが長かった)。
ただし、ロングバージョンでは、スクリプトの最後にws.run_forever()といかにも永遠に存続する気満々そうなメソッドがあり、スクリプトを直接起動するとジョブが、音声操作経由だとプロセスが残り、なぜか、対象デバイスへの操作が2件ほどたまると以後、対象となるESPボードを使ったガジェットの操作ができなくなり、kill/pkillすると操作できるようになります。
かと言ってpythonスクリプト内でどうにかする方法をにわかには思いつきませんでした。
そこでスマートスピーカー応答用スクリプトvoicereceive.plの当該操作行(Perlスクリプトでシェルや他スクリプトを実行できる[system("...")])に続けて実行スクリプト自体のプロセスをkillできるようにperlの関数なのでそのまま、sleep(2);、更に続けて次行にsystem("pkill -f スクリプト名");などとし、これらの変更を有効にするために当該デーモンをsystemctl stop/daemon-reload/startしました。
sleepを入れたのは、ショートと同じようなことになるようで入れないと機能しなかった(成功率がめちゃめちゃ下がって検証にもならなかった)からです。
あとPC/Debian Busterには入っていた一方、Raspberry Pi/Raspbian Busterには入っていなかったlibwebsockets8を一応インストール(apt install)しておきました。
ロングバージョン(Long-lived connection)は、こんな感じになります。
引数をとるべく、sysをimport、Python3では、threadに前置詞アンスコを付けた_threadになった模様、自身は3しか使わないのでこのように変更(あれ、importしても省略できないんだ...)、threading...の出力、トレースは不要なのでコメントアウトしました。
前述のようにスクリプトを直接実行(./any_script.py 1 &)した場合、プロセスが残るのでkill/pkillしておく必要があります。
音声操作時には、その必要がないように例えば、voicereceive.plにsleepとpkillを追記します。
気づけば、websocket-client-py/websocket-client-py3がバグっているのか、大幅に仕様が変わったのか、ショートバージョンはことごとく効かず、ロングバージョンは投げたら返ってこなかったり、エラーを吐くようになっていました。
そこでpip(pip3)でインストールできるwebsocketsバージョンにしたところ、returnを入れても入れなくても、いけました。
ちなみに自身は、スマートロールスクリーン、スマートカーテン、スマートペンダントライト、スマート化した壁スイッチのシーリングライトなどをこれに入れ替えました。
このところ、家電についてはスマホやパソコンからパネル操作ばかりで音声操作していなかったので気づきませんでしたが、いつ頃からだったんでしょうね?
詳細は、冒頭の自作IRリモコン、自作スマートコンセントのリンク先に譲りますが、これらを必要に応じて用意し、このようなスケッチを書いてアップすることになります。
今回使ったラフスケッチは、これ。
仮にこのまま使う場合、少なくとも宅内・社内無線LAN用のssid/password、ESPモジュール・アクセスポイント用のSOFTAP_SSID/SOFTAP_PWは、実際の環境に合わせて設定する必要があります。
信号出力ピンは、スケッチにIRsend irsend(2);とあるようにGPIO2を使いました。
とりあえず、テレビ(検証したのはSHARP AQUOS)のON/OFF用だけ書きましたが、エアコンでもファンでも何でも必要に応じて追記すればよいし、個別に作るなら、GPIOピンは1本で足り、併用するなら、その数に応じてESPモジュールを選ぶと良いでしょう。
ちなみに声で操作もできますが、例えば、http://esptv.local/TV1/Powerのようにブラウザからアクセスするだけで機能しますし、SPIFFS関連コードも一部書いてはあるも実装していませんが、handleルートにアクセスしたらindex.htmlを展開すれば、声でもブラウザからでもON/OFF以外の各種操作やESPリモコン回路を併用するなら他機器への操作を併用もできるでしょう。
どっちでも機能するのは、(Web|USB)カメラなどを使って赤外線発射の動作確認する際にも便利。
半完成品状態の今回は、実行する場合、一部順不同な部分もあるも概ね以下のような手順となります。(JuliusやOpen JTalkについての設定詳細は、前述、もしくは後段関連リンクの各リンク先参照。)
終了する場合は、どちらも端末から起動した場合は、[Ctrl]+[C]。
場合によっては、スクリプト側は、ps aux | grep するなどしてkillせざるを得ないこともあるかも。
ここでは、操作の合言葉として元のスクリプトのフレーズ「スタンバイ」を使わせて頂いていますが、「ヘイ、Siri ...」、「OK、グーグル ...」、「アレクサ ...」のように、それっぽくするのも簡単で、辞書とスクリプトの当該箇所を変更するだけ。
逆に言えば、誤認識がなく、ちゃんと認識されるフレーズであれば、他に制約なくウェイクワードとすることができます。
先のサンプルスクリプトの通りだと、次のような感じになります。
家電については例えばテレビなら「テレビをつけて」「テレビを消して」という声に反応して「テレビをつけます」「テレビをけします」という女声メイさんの日本語音声による応答とともに既に電源が入ってついているか、リモコンで電源を切ってあるテレビのON/OFF操作ができます。
尚、リモコン信号は、テレビに限らず、各電気製品のメーカーや機種のリモコンに合わせたものに変更する必要があります。
また、「今日何日」「今日何曜日」「今何時」とか、「今日の天気」「明日の天気」「明日の気温」にも日本語で答えてくれます。
もちろん、「照明」/「冷房」/「暖房」/「除湿」+「つけて」/「かけて」/「して」/「起動」/「消して」/「消す」/「停止」などと既に辞書登録、Perlスクリプトに追記してあるものも、ESP回路を併用したり、別個に作ったりしつつ、それに合わせたコマンドなどをPerlスクリプトに追記するだけで使えるようになります。
更なる機能追加もできますが、どれだけ無線でぶら下げられるかは、WiFiルーターやアクセスポイントの性能次第な部分もある?
ちなみに、びっくりするほど読みが正確なOpen JTalkも漢字の「除湿」を「じょしめ」と読んでしまいますが、スクリプトjsayに渡すときに「じょしつ」や「ジョシツ」とひらがなやカタカナにすれば、とりあえず、回避できます。
スマートスピーカーを買ってみようと思うほど興味はなかった自身も基本、完成品の組み合わせで手を加えたのは、ほんの少しながら、自作できてみると迂闊にもちょっと感激。
とりあえずHTTPアクセスした部分は、HTTPSアクセスにする他、あらゆる面でセキュリティは注意の上にも注意が必要でしょう。
ラズパイ、Julius、Open JTalkのみならず、コンピュータビジョンやAIも取り込んでいるらしき、OpenCVやTensorFlow/Kerasまで使ったスマートスピーカーを公開している方がいた...。
やっぱり買うには少し高いな。スマートスピーカーの作り方教えちゃいますってコレもなかなかおもしろいかも。
ラズパイ+Google AIYで日本語対応スマートスピーカーやRaspberry Piで日本語Alexaの方がスマートか。
いや待てよ?Raspberry pi3でAIスピーカーをガッツリ自作が、すごいか。
本文では、スマートスピーカー用のラズパイを買う前にLinuxパソコンでの話でした。
が、いざ、Rapsberry Pi 3 B+を買ってDebian環境からJuliusディレクトリをコピー(scp)して実装してみるとラズパイならでは、Raspbian Jessie/Stretchならでは、ラズパイ3B+ならではの違いがあり、代替・追加作業が必要となりました。
具体的には、以下で他は、同じです。
ALSAではなく、JuliusでPulseAudioを使うこともできました。
マイクでも想定外の状況に遭遇しました。
検証に使った2つあるUSB接続のWebカメラ内蔵マイクは、パソコンと内蔵スピーカーや簡易ヘッドセットのイヤホン、3.5mmミニジャック接続の100均スピーカーでは、音質はクリアに録音・再生でき、ラズパイではこれら組み合わせで僅かにノイズものりつつも気にならないレベルで正常に再生できました。
ですが、オーディオ・サウンドカードとUSBサウンドアダプタと音量調整付きUSBサウンドアダプタにある2つのUSBサウンドアダプタと先のWebカメラに付属の簡易ヘッドセットのマイク、同ヘッドセットのイヤホンや3.5mmミニジャック接続の100均スピーカーとの組み合わせだと、何れもラズパイUSBポートに直挿しでもUSB延長ケーブルを介してもマイク入力時のノイズが激しすぎて話になりませんでした。
また、ラズパイに元々入っている(/usr/share/sound/alsa/の)音源は、簡易ヘッドセットのイヤホンや100均スピーカーをUSBサウンドアダプタに挿しても、ラズパイの3.5mmミニジャックに挿しても音質はクリアなので少なくともUSBサウンドアダプタとスピーカーやイヤホンの組み合わせに起因するものではないと考えてよさそう。
となるとマイク入力においてラズパイUSBポート付近の何かに影響を受けているようですが、それでもWebカメラ内蔵マイクは十二分に許容範囲内であり、ならば簡易ヘッドセットのマイクが原因かと思いきや、『2つのWebカメラ』のリンク先の流れでDebian/Fedora/NetBSDでの通話テストでは、簡易ヘッドセットはマイク・イヤホンともに、またWebカメラと合わせて正常に使えたので、性能というか、あるとしたらノイズへの耐性の違い...?はたまた、USBサウンドアダプタに起因?
そもそも、マイクは、別途購入した3.5mmミニプラグのものを、スピーカーもできれば手持ちの100均の3.5mmミニジャックを予定し、USBサウンドアダプタを介すこと前提で想定していたのですが...。
ただ、マイクが届いてみると4極プラグでパソコンでは完璧に機能したのですが、3.5mmミニジャック(及びプラグ)が先端からLEFT/RIGHT/GND/映像の4極らしきラズパイでは、プラグから分岐しているスピーカー出力用ジャックは機能するも肝心のマイクは残念ながら機能しませんでした。
と思ったら、3極である簡易ヘッドセットのマイクをラズパイの3.5mmミニジャックに挿してみたところ、録音できない...、そもそもラズパイの3.5mmミニジャックは映像とあることもあって、マイク入力に対応していないのか...?
これらのことからするとラズパイについては、マイクはUSB接続のものが良さげ、とすると、これを別途調達するなり、Webカメラ内蔵マイクを使うなりといった計画変更が必要になりそう。
尤も100均のスピーカーも、音が小さすぎ、PulseAudioで最大(153%)にしてみたところ、そこそこで音量調節せずに使うならよいかなと思わなくもありませんが、やはりアンプ?でもかまさないといけないかとは思っています。
ラジオ機能追加に伴い、試しにここで使った手持ちのLogicool Z120BWを接続してみたら、音量問題もすっきりクリア、やっぱり、ある程度、ちゃんとしたスピーカーじゃないと...と思いました。
しばらく使ってみたら、スクリプト内で書くと実行時から更新されないということに気づくドジっぷり...日付時刻は、今回使ったWheather Hacks含め、Web APIから取得したものを使うか、dateコマンドから加工したスクリプト使った方がよさ気。
ラズパイはまだもノートパソコンで自作スマートスピーカーの自動起動をやってみたら、思いの外、ハマりましたが、結果、/etc/rc.local等々を使う方法でできました。(詳細はリンク先参照)
ノートか、ラズパイか、何れのスマートスピーカーで使うか、使えるかは、まだわかりませんが、侮れないらしきダイソー300円スピーカーを買ってみたら確かに良品でした。(詳細はリンク先参照)
自作ラズパイスマートスピーカー自動起動設定完了、ノート同様にはできず、systemdで実装。
今、自作スマートスピーカーは、リビングダイニング、キッチン用にしてあります。
とりあえず、スマートスピーカ構成品の筐体として少し大きめのダンボール(Amazon発注品が入っていた片開きタイプ WxDxH:330x225x120mm)に入れてあります。
ダンボール内には、転倒防止、保護クッション、遮熱?として滑り止めマットを敷き、USBメモリブートで冷却ファン付きケース入り、各所にヒートシンク装着のラズパイ3B+、スピーカLogicool Z120BWを並べ、後述の理由からマイクとしてマイク内蔵WebカメラELECOM UCAM-220FEは外出しにしてあります。
スピーカーとマイクが反対(スピーカーの背面にマイクが来る)方向になるよう冷蔵庫の上にスピーカー、マイクが側面になるよう横向き?にし、キッチン側にマイクが来るように置いてあります。
冷蔵庫は壁を背に上方、前面、側面は開放状態、冷蔵庫正面から見て右方向がキッチン、左方向がLD。
音が篭もらないようスピーカーホーン部と前面にあるボリュームボタン部のダンボールは切り欠き、できる限り音声認識感度を広くとれるよう試行錯誤した結果、マイクとしてのWebカメラは、箱に入れず、冷蔵庫側面にぶら下げてあります。
比較的室内の反響が良いためか、リビングでテレビがついていて、キッチンで換気扇が動いている程度の環境でウェイクワードを発する場合、それなりに声を張れば、3m程度離れても音声操作可能となっています。
ただ、マイクと一定の距離があるとは言え、スピーカー音量を一定以上上げると操作音声を認識できず、反応しないし、相応のボリュームにしておき、マイクと反対になるスピーカー側から音声操作できることもある一方、原因不明も何かの折には、極力マイク付近に近寄らないと音声操作できないこともあります。
少し甘めの評価かもしれませんが、それでも実用的と言ってよいレベルと認識しています。
こうした設置場所の場合、例えば、献立考え中、調理中や洗い物中、食器の出し入れ中、掃き掃除や拭き掃除中、部屋、バス、トイレ、玄関に行く・戻る途中、もの思いにふけりつつ、家電操作したり、ニュースや天気、ラジオを聴くために音声操作できます。
前述の通り、PCにもスマートスピーカ機能を入れていますが、記事やプログラム作成中、調べものなどネット閲覧中等々、キーボード、マウス操作中でも、ながら音声操作できます。
もちろん、PCを起動すれば、SSHやVNCでラズパイスマートスピーカにアクセスし、新機能を搭載したり、編集したりと自由自在。
当初、そんなもん要らないでしょと思っていた自身ですら、実際使ってみると、こうしたあらゆるシーンで何かしながら音声操作できることに利便性を感じ、とても重宝しています。
試行錯誤中はそうもいきませんが、ある程度、一定の機能性を保持できるよう調整できた後は、時に感度がよくないことがあるとややストレスが溜まることもないわけでもありませんが、そこは自作した満足感も手伝ってか、かわいいものだと思えます。
自作、自作と言っても様々な素晴らしい出来合いのものを組み合わせたに過ぎませんが。
モニタやマウス・キーボードのないIoTデバイスとしてのラズパイ用に、別途PCを起動しアクセスしなくても起動、再起動、シャットダウンできる物理ボタンがあると便利。
例えば、メインスクリプトは起動したのにJuliusの起動に失敗した(スマートスピーカーがうまく応答しないといった)時などには、ラズパイに専用の再起動ボタンがあると、コンセントの挿抜やスイッチON/OFFで電源を切るのは乱暴なのでシャットダウンボタンがあると、シャットダウンしてみたけど、やっぱり起動という時、コンセントの挿抜・スイッチOFF => ONするまでもなく、シャットダウンと同じボタンを押すことで起動できると...など。
併せてラズパイACアダプタをスイッチ付きコンセントに挿し、シャットダウン後、コンセントのスイッチでOFF(電源断)できるようにしました。
もちろん、スイッチ付きコンセントのスイッチONでもラズパイは起動します。
ラズパイスマートスピーカーでUPnP/DLNAサーバ上のメディア再生機能を追加。
例えば、手持ちの音楽CDなどをリッピングしてサーバにアップしておけば、自分だけのオリジナルの音楽ライブラリを任意の音声操作で再生・停止できます。
もちろん、メディアサーバのストレージが許す限り、音源追加は自由にできます。
自身の場合、他サーバ機能含め、メディアサーバもラズパイ、現在、ストレージは、HDD 2TB。
今は、「音楽かけて」と呼びかけると「CDコレクションを再生します」と応答後、再生が始まる(シャッフルし、再生する度に曲順が変わる)ようにしてあります。
ラジオ再生において、これまでの、らじる★らじるを含むradikoやサイマルラジオ各局の他、IcecastストリームからJazz、Classicに加え、Blues放送局を追加、呼びかけワードは、まんま「ブルース」。
気がつけば、言いよどみがあり、記憶が曖昧だったのでjsayスクリプトで単に"睦月・如月・弥生..."といった旧暦の月を読ませるold_month.shを作成、追加、コールワードは、「旧暦の月」。
尚、Open JTalkの読み上げにおいて「文月」の「ふづき」は、「ふみづき」と併せ、これも正しいと思われるので漢字のままも、「神無月」は「かみなづき」と読み、間違いではない気もしますが、一応、これだけ平仮名で「かんなづき」としました。
これらを反映させるため、何れも応答スクリプト、Julius辞書への追記、Juliusオリジナル辞書ファイルエンコーディングをeucjpへ変換、systemctlでstop/disable/daemon-reload/enable/start。
ちなみに先日、テレビでスマートホーム三昧の方が出ていてGoogle Homeの音声もチラッと流れていましたが、それを聞いた限りにおいては、明らかにOpen JTalkの方が、イントネーションに違和感がないように感じました。
仕組みからして元々、定型アクションを登録・実行できることを明記。
自作ラズパイスマートスピーカーでテレビを音声操作する方法の概要を追記。
ほぼ全て既存機能ながら以下の機能のページを起こしました。
自作ラズパイスマートスピーカーでエアコンを音声操作する方法の概要を追記。
リモコン付きラズパイスマートスピーカーで空気清浄機を音声操作と同じくスマートスピーカーでリモコン付き扇風機を音声操作する方法の概要を追記。
何れもリモコン非対応の自作スマートスピーカでサーキュレーターを音声操作、自作ラズパイスマートスピーカーで扇風機を音声操作、自作ラズパイスマートスピーカで蚊取器を音声操作する方法の概要を追記。
時・分指定(時間指定)、分指定(カウントダウン)できるタイマー機能追加。
Julius、Juliusが起動済みであること前提の応答スクリプト共に起動したかと思いきや、たまに応答スクリプト起動直後にJuliusが落ちる現象に遭遇。
運用でごまかして先送りしていましたが、向き合ってみたら、なんてことはない応答スクリプトから簡単なシェルスクリプト作って呼び出すことで対処できました。
これまで応答スクリプトが起動した時点で応答スクリプト内で「音声操作の準備ができました」というメッセージを流していましたが、これを「音声操作の準備中」とし、直後に(Perlスクリプトなので)system("/path/to/julius_chk.sh &");としてチェックスクリプトを呼び、sleepで適当な秒数待ってpgrep -fでプロセスの有無を確認、ない場合、systemdサービスを再起動するだけ。
もっと早くやっておけばよかった...。
音声メモ機能と伝言メッセージ機能を追加しました。
音声メモは、なんでもメモる、伝言メッセージは、伝言に限る、何れも複数件登録可能、削除時は、全件削除。
実際には、保存先のファイルパスが違うだけで、どちらも同じですが、運用で使い分ければよいかなと。
音声メモと伝言機能追加に伴い、Juliusを少なくとも4.4では選べるPulseAudioを使うべく再コンパイルしました(かかる時間は極わずか)。
OSSやALSAは、マイクやスピーカーといったハードウェアを占有してしまう性質があり、仮想デバイスとして同時に複数の使い道で使い分けることができませんが、PulseAudioなら、これらを使用しつつ、仮想デバイス化できます。
これまで(OSSや)ALSAを使っていたため、音声メモや伝言メッセージ機能を追加したはいいのですが、いざ、使おうと思うとマイクとスピーカーを専有され、なんとスマートスピーカー機能側で使えないという状況が発生したわけです。
ログインすることなく、YouTubeの任意の音楽動画のプレイリストをyoutube-dlでダウンロード・保存、これをランダムに並べ替えつつ、youtube-dl/mplayerで各動画をストリーミングすることでシャッフル再生、副産物としてスキップ機能も実装することにしました。
RadikoやICECASTで満足していたのですが、音楽に限らず、何か追加する機能ないかなと思いにふけった結果、なんとなく。
ラズパイスマートスピーカーにモニタは搭載していませんが、ノートPCならPCに搭載のスマートスピーカー機能はもとより、sshでラズパイ側のスマートスピーカー機能をGUI操作できるわけで、あってもよいかなと。
より複雑なGUIパネルを作りたいと思い、GTKより、やや情報が多かったQtで作ってみました。
以下は、後述の2つの要因により、PC版ではなく、ラズパイ版スマートスピーカーのみで結果的に消失したfeedparserのインストールとmplayerの代替としてmpvを使うべくスクリプト修正することになった話です。
たった今まで再生できていたICECASTやYouTubeの音楽の再生が突如としてできなくなったり、livedoor天気が聞ける一方、Yahooニュースが聞けなくなったりする事態に遭遇しました。
当事象は、ラズパイ(OS:Raspbian)スマートスピーカーのみであり、PC(OS:Debian)に入れたスマートスピーカーでは何れも機能する、ラズパイスマートスピーカーにssh/scpアクセスはできる、ということで自作systemdサービスファイルやそこから呼ぶファイルの確認やsystemctl stop/disable/daemon-reload/start/enableを何度か試すも相変わらず。
とりあえず、Yahooニュース取得スクリプトを眺めていたところ、そう言えば、これが、apt update/upgrade後に起きたことから、Debian StretchからBusterにアップグレードした際、pip3でインストール済みのfeedparserが、なぜか、消えていたことを思い出しました。
思ったとおり、pip3 list | grep -i feedparserしてもなく、pip3 install feedparserしたところ、これを使っていたYahooニューススクリプトが機能するようになりました。
続いてICECASTやYouTubeの取得再生スクリプトを眺め、何気なく、端末で直接mplayer URLしてみると[mplayer: relocation error: mplayer: symbol av_alloc_vdpaucontext version LIBAVCODEC_58 not defined in file libavcodec.so.58 with link time reference]なる見慣れないエラーが。
検索してみると昔からたまに起きていたmplayerのバグらしく、一瞬、ダウングレード...とも思い、Raspbianながら、DebianのAPT_PREFERENCES(5)を見ると積極的にやりたい方法じゃないな...と。
そう思いつつ、そう言えば、mpvってMPlayer/MPlayer2ベースの動画含むメディアプレイヤーだったような...。
ならば代替が利くのでは...。
ということで各種スクリプトのmplayer部分をmpv(前者の-novideoオプションは、後者の--no-videoオプション)に替えてみると無事、機能するようになりました。
また、ラジオ等停止スクリプトにpkill -f mpvを追記、YouTubeプレイリストのスキップ用スクリプトは、mplayerではプロセスがyoutube-dlでしたが、mpvでは、mpvとしてあったため、こちらもpkill -f mpvとしました。
というわけで、これらの事象は、アップグレード中になぜか、feedparserが消失したこと、本体もしくは依存関係にあるパッケージがアップグレードしたからかmplayer([arch]armhf/[バージョン]2:1.3.0-8+b3)のバグの2点が原因でした。
ちなみに問題のなかったPC/Debian amd64の方のmplayerのバージョンは、2:1.3.0-8+b4でした。
今日、PC版スマートスピーカー機能においてもICECAST、YouTube共にmplayerだと正常に再生できず、mpvに変更することになりましたが、以前確認したバージョン(2:1.3.0-8+b4)と変更がないことから、mplayerのバグに起因するものではないようです。
尚、スクリプト修正後、systemctl restart ...が必要でした。
自作ラズパイスマートスピーカーで自作電動ロールスクリーンを音声操作する方法の概要を追記。
自作ラズパイスマートスピーカーで壁面照明スイッチを音声操作する方法の概要を追記。
自作ラズパイスマートスピーカーでペンダントライトを音声操作する方法の概要を追記。
自作ラズパイスマートスピーカで電動部自作カーテンを音声操作する方法の概要を追記。
ラズパイ+ZoneMinderによるカメラ映像を音声操作とGUIスクリプトパネルから操作できるようにしました。
スマートスピーカー機能を入れたLinuxパソコンやラズパイから音声操作や自作Qt GUIパネル操作でJitsi Meetによるビデオ会議、内線ビデオ通話画面(ブラウザ)を起動できるようにしてみました。
インターネット経由では自端末のみ、内線通話を意図して同一ネットワーク内であれば、自端末だけでなく、起動中の他端末のJitsi Meet画面を相互に開くようにしています。
スマホやタブレットもJitsi Meetアプリ必須ではありますが、もちろん参加可。
YouTube、radiko、ABC World News BBC World News、internet-radio.com、ICECAST、自前カセット、CDやMDなどをリッピングしたものなどのストリーミング再生において、なるべく均一になるように音量を調整してみました。
先日、カセットテープをリッピングしてサーバにアップしてみたら、相応に出力調整はしたのですが、他と比し、出力音量が小さめだったので、これに合わせようかと。
他のオプションもありそうですが、mpvは[--volume=val]、mplayerやffplayは[-volume val]で調整しました。
機能追加というわけではないのですが、スマートスピーカーの設置場所はそのままに、Bluetoothスピーカーを使って電波到達範囲において聴取範囲を変更できるようにしました。
原因不明のBluetooth接続後、即切れ対策のスクリプトをcronで走らせることでBluetoothスピーカーのON/OFFでBluetoothスピーカーとスマートスピーカー側スピーカーの自動切り替え、Bluetoothスピーカーの電源が入った状態でスマートスピーカー再起動後にBluetoothスピーカーで再生も可能になりました。
ラズパイスマートスピーカーのシステムディスクとして使っていたUSBメモリ内のシステムがおかしなことになり、Raspberry Pi Imagerで同じUSBメモリに焼き直し、イチから構築し直しました。
同じUSBメモリへの焼き直しは、若干迷いましたが、apt upgradeをさぼって対象が100件超えていたところでlibc6の依存関係エラーからの/var/lib/dpkg/info内の*.listファイルの最後に改行がないエラー、1つ1つ入れていき、これを解消するも他のエラー...でお手上げとなり、USBメモリ自体というより、システムだよねということで。
Juliusについては現時点の最新バージョン4.6をセットアップ、UTF-8に統一されており、dictationキットの辞書も小細工は不要、他方、マイナーチェンジがあったのか、Raspberry Pi OSにおいてデフォルトのサウンドサーバがpulseaudioからalsaに戻っており、一時消滅していたconfigureオプション[--with-mictype=]が復活していました。
結果、Juliusのコンパイルは、次のようにしました。
$ ./configure --enable-words-int --build=aarch64-unknown-linux-gnu --with-mictype=pulseaudio
[--enable-words-int]は、githubにあったので、[--build=aarch64-unknown-linux-gnu]は、./app/julius/support/config.guessの出力結果、そして復活していた[--with-mictype=pulseaudio]。
当初、[--enable-words-int]だけでやってみると[configure: error: cannot guess build type; you must specify one]、途中のメッセージに沿ってconfig.guessとconfig.subの対処するも、再実行すると先のエラーに加え、[configure: error: ./configure failed for jcontrol]。
How to resolve configure guessing build type failure?の通り、automakeをインストール、/usr/share/automake*/にあるconfig.guessとconfig.subに差し替えても変わらず、と思いきや、そのリンク先の[For arm64]にある通り、先の値を[--build]オプションに渡してやってみたところ解消・解決、加えてpulseaudio対応した次第。
先日、赤外線リモコン付きから買い替えたスマート家電の空気清浄機、必須となったという会員登録・ログイン・クラウドを回避しつつ、ブラウザ操作パネルと操作スクリプトを自作してみました。
というか、このJulius/Open JTalkスマートスピーカー用スクリプトからスマート空気清浄機用の自作スクリプトをファイル名+引数で操作できるようにし、Amazon AlexaやGoogle Homeでなく、Julius/Open JTalkスマートスピーカー専用機からでも、同機能を入れた2台のパソコンからでも音声操作できるように、そうしました。
また、スマート家電空気清浄機用の自作操作パネルはWebサーバを建てIPアドレスやmDNSで呼べるようにしてJulius/Open JTalkスマートスピーカー用に作ったQt操作パネルやESP32ボード上のスマートホーム操作パネルからも簡単に呼べるように作ってみた次第。
購入から5年ちょい、なんちゃらカメラ用に仕込んでいたラズパイ3B+を1台ショートさせ壊してしまったのでスマートスピーカーの3B+を回すべく、Orange Pi Zero 3にJulius/Open JTalkスマートスピーカーを移行しました。
あ、家電操作を含めるとスマートリモコンも買わないといけないのか...すると更に1.5〜2倍くらいだとして3万円前後になる?
そうだとすると自作は価格メリットもあるか...。
それに実際使ってみると自作のメリットは意外と多いかも。
Google AsistantやAmazon Alexaなどもラズパイに実装できるため、ラズパイに注目すると焦点がズレる可能性があり、スマートスピーカーについては、音声認識・音声合成がローカル上のJulius・Open JTalkかクラウド上のAIかの比較といえるかも。
どっちにしても誤操作については、考慮しておく必要がありますが、在宅時は対処できるとして外出時に電源をOFFにするという運用をすれば問題ないでしょう。
一方、スマートスピーカーに限らず、外からの家電操作を行なうことも不可能ではないし、スマートロックとカメラによる確認は便利かもと思うものの、特段必要性を感じないという以前に疑問符もあり、現時点では、実装していません。
この中の一部については、不在時のタイマー起動にもあてはまるものも。
Chainerも入れたりしたけど、TensorFlow、Kerasを使ってみるべく、pyenv、virtualenvなどと比較検討した結果、検討時点で想定はしていたことではありますが、anaconda3を介したら、Pythonバージョンが上がってシステム側もPython3を強制使用するようになってしまう関係で自作スマートスピーカーにおいて呼び出していたPython2ベースのスクリプトでエラーになり、スクリプトをPython3ベースに修正する必要がありました(anacondaを削除すれば、強制されないため、これを削除するっていう手もありますが...)。
結局、Dockerを使うことにし、anacondaを削除したのでホストOS上のPythonバージョンに影響はなく、問題は解決。
冒頭追記のようにRaspberry Pi 3 Model B+を買って実装、3B/3B+ならではのUSBブートしているわけですが、スマートスピーカー機能とは別にどういう訳か、人気があるらしきWeb|USBカメラLogicool C270をラズパイに挿しておくとブートするはずのUSBが起動しないという事象に遭遇。
試しにUSBサウンドアダプタ、もう1つ手持ちのUSBカメラELECOM UCAM C0220FE(C0220FEWH)、更には、レスキュー用Live USBを挿してみましたが、何れも正常にラズパイブート用USBからRaspbianが起動することを確認済み。
なぜだ...例えば、C270の消費電流が他に比べ、一時的にでも相当に高くなり、電流不足に陥っているのか...?、はたまた、他のUSB機器との違いとしてはC270には、ケーブル上にフェライトコアが付いていますが、これの影響があるのか?ちなみにUSB延長ケーブルを介してみても変わらない...。
尚、C270もラズパイ起動後に挿せば、内蔵マイクも使えるし、以前、ラズパイ2Bでmotionを試したときもカメラとして使えたはず...。
ん?2Bならいけるのか?と現在サーバとして使っているRaspberry Pi 2 Model Bで試してみるとC270をつないでおいてもラズパイが起動する...。(いや、勘違い2B+のブートはmicroSDで自身の場合、システムはUSBもmicroSDから固有のものを呼んでいるからUSB内のシステムが起動するのは当たり前...。)
ということは、フェライトコアの可能性は消えたと考えてよいだろう、すると3B+との相性...か、なんら異常は見られず、機能していますが、手持ちの3B+の不具合か...、高性能になり消費電力が高くなった3B+に加え、C270が他より高い、結果ブートに影響...という可能性もなくもないか...?
幸い、これとは別にラズパイと古いパソコン周辺機器を組み合わせてパソコン化を検証してみる為、Aliexpressではありながらも違う店にRaspberry Pi 3 B+を発注してあるので届き次第、試してみようと思います。
後日、試してみましたが同じでした...、となるとRaspberry Pi 3 Model B+とUSB HDDブートでも触れたように電源容量関係かもしれません。
今回、ARM クアッドコアCPU 1.4GHz、1GB RAMのRaspberry Pi 3 Model B+でスマートスピーカーを作ったわけですが、一方でIntel Celeron デュアルコアCPU、4GB RAMのノートPCにも同じスマートスピーカー機能を入れています。
そんな中、ふと気づいたのが、ノートPCに比し、ラズパイの方は、インターネットラジオ再生に若干遅延がある(同じ局を再生すると輪唱のようになる)こと。
だからと言って再生速度が遅い(スロー再生される)わけではないので困ることは一つもないですけど。
ちなみに同じ光ONUに有線接続した無線LANルーターを介し、ルーターから同じ距離に置いたPCとラズパイ(スマートスピーカー)で比較してみた結果、WiFi電波到達範囲内においては距離は関係ないようです。
内蔵無線LANドライバの違いの可能性もなくもないかとも思わなくもありませんが、無線LANでの動画ストリーミング再生遅延にはRAM増強が有効であるという実体験からしてCPUはさておき、PCは4GB、ラズパイは1GBというRAM容量の違いが、この遅延に起因しているのではないかと思っています。
技適はまだな模様もRAM1GB版に加え、2GB、4GB(、8GBもありそうな雰囲気)もあるラズパイ4Bなら、この仮説を検証できるわけですが、今のところ、その予定はありません。
前述の通り、Raspberry Pi 3 Model B+とWeb|USBカメラLogicool C270の相性がよろしくないのでC270をメインのノートPCで、ラズパイスマートスピーカーではELECOM UCAM C0220FE(C0220FEWH)をつかっていました。
が、ここにきてC270のカメラ機能が壊れたこともあり、昨日、ヨドバシ(yodobashi.com)でBUFFALO BSWHD06M/BSWHD06MWH [マイク内蔵120万画素Webカメラ HD720p対応モデル ホワイト]を買ってみたところ、より感度が良さそうなこともあり、これをラズパイスマートスピーカーのマイクとして使うことにし、UCAM-C0220FEをメインPC用としました。
自作スマートスピーカー製作以来、唯一、piアカウント使ってしまっていたのですが、ここでpiを削除、新規アカウントで運用することにしました。
運用中の削除は、そこそこ面倒、セキュリティ面からは必須なので新規アカウント登録、piアカウントの削除は、初めに行っておきましょう。
ただ、他にも次のようにやることはあるものの、後で気づけば、piユーザを使えないようにするは、良い手かも。
運用アカウント変更に伴うパス変更。
piアカウントが存在する状態で先に新規アカウントを作ってしまった場合。
リンク先に倣ってユーザー名piを移行先運用アカウント名に変更。
この時、piアカウントが存在する状態で先に新規アカウントを作ってしまった場合、1は既に存在すると言われる。
piアカウントの権限削除。
改めて、ここでpiアカウントが存在する状態で先に新規アカウントを作ってしまってnew_userにpiとは別のgid/uidを割り振られている場合。
気のせいか、bullseyeだからか、useradd -sでログインシェルを指定することは久しくなかった気がするのですが、省略したらシステムデフォルトとして純粋な/bin/shが選択されていることを上キーで文字化けし、historyコマンドがないことで気づくに至り、シェル変更。
ssh経由で電源を落とすべく、ユーザーアカウントからパスワードなしでsudoを使いたいので/etc/sudoers.d/010_pi-nopasswdを次のようにした。
あとは念の為、スマートスピーカーへのsshで楽するため、スマートスピーカーのホスト上でrm /home/new_user/.ssh/*後、他のホストから必要に応じて(ssh-keygen/)ssh-copy-id -i 公開鍵.pub スマートスピーカー.localやIP。
このくらいだったかな。