嬉し恥ずかしお百姓Season2(12):ブルーベリー収穫期
園芸 [2020/07/23]
ちょっと前に書きましたが、今年はなんだかブルーベリーの実付きがいい気がする。
棲家にある親木の実が、そろそろ黒くなりだしたと思って見に行くと、
熟しかけの実から順次、突かれた跡があります。
朝方のチュンチュン声と、日中のヒーヨヒーヨと鳴く連中の仕業だと思います。
たぶん定期巡回コースになっているだと思います。
3分の1から半分くらいは、傷物になってます。
クソッ。
堪らず、網掛けをしました。
数年前に買ってあった網を引っ張りだしましたが、木が大きくなってるのでたぶん寸がちょっと足りません。
なので、支柱と杭を買ってきて、こんな感じに仕上げました。

杭を打って、それに新しい支柱を結わえて。
前に使ってたアミ+プラスチックの骨を支柱に麻紐か洗濯ばさみ(デカイヤツ)で固定しました。
天井は、余ってたアミを被せて、支柱に麻紐で結わえた。
前面は開けられるようにしてます。

前と後ろと上のガードはOKですが、左右は網が足りなかったのでフリーです。
でも、アジサイの木が幾分ジャマするので、これでなんとか忌避効果にならないかと・・・
棲家にある親木の実が、そろそろ黒くなりだしたと思って見に行くと、
熟しかけの実から順次、突かれた跡があります。
朝方のチュンチュン声と、日中のヒーヨヒーヨと鳴く連中の仕業だと思います。
たぶん定期巡回コースになっているだと思います。
3分の1から半分くらいは、傷物になってます。
クソッ。
堪らず、網掛けをしました。
数年前に買ってあった網を引っ張りだしましたが、木が大きくなってるのでたぶん寸がちょっと足りません。
なので、支柱と杭を買ってきて、こんな感じに仕上げました。

杭を打って、それに新しい支柱を結わえて。
前に使ってたアミ+プラスチックの骨を支柱に麻紐か洗濯ばさみ(デカイヤツ)で固定しました。
天井は、余ってたアミを被せて、支柱に麻紐で結わえた。
前面は開けられるようにしてます。

前と後ろと上のガードはOKですが、左右は網が足りなかったのでフリーです。
でも、アジサイの木が幾分ジャマするので、これでなんとか忌避効果にならないかと・・・
スポンサーサイト
スマフォのアプリを作りたい(29):スマフォだけで動作する音声認識⑤
プログラミング [2020/07/19]
JuliusをAndroidスマフォ上で動作させたいと思ってます。
概ね
Ⅰ.まずはJavaコードからC関数を呼び出すようなアプリの作り方を調べます。
Ⅱ.Javaコード(Cライブラリ含む)をReact Nativeで使えるパッケージ化方法を調べます。
Ⅲ.React Nativeにパッケージを取り込んで、Build&Go。
の順番で進めてますが、5回目にもなるのに未だⅠの途中です。
前回、AndroidStudioのデバッグ機能を有効に動作させるための設定に1週間程費やしてしまいました。
今回は、その続き。
なんとかデバッグできる環境にはなりましたが、未だ不足している部分があります。
◆標準出力に出るメッセージが見たい
JuliusLib(libjulius&linsent)内で、メッセージ出力にprintf/fprintfが使われています。
「それってAndroid上ではどうなるの?」と調べたら、「logcatに出力される。」という記述をどこぞのサイトを斜めに読んで見つけた。
でも、実際はそんな簡単ではなくて、「だまっててもlogcatに出力される」ようにはなっていませんでした。
「リダイレクトすれば見える」というような記述もあって、その通りやってみた。
でも、どうも出てるようには見えない。
さらに調べると、なんか色んなことが書いてあって却って面倒そう。
しかたなくJuliusLibのソースに少し付け足しすることに方針転換しました。
プリプロセッサのマクロ定義を使って、printf/fprintfをAndroidのlogcat出力関数に置き換えてみました。
まずは、julius.hの終わりにヘッダファイルの#includeを追加します。
新規追加したヘッダの中身は、こんな感じ。
julius.hと同じフォルダ「(プロジェクト・フォルダ)\app\src\main\cpp\libjulius\include\julius」に追加しました。
ちなみに、マクロ・ヘッダの#includeは「#include <stdio.h>」より前にあるとダメです。
本体の関数定義も置き換えようとしちゃうから。
ちょっと、こんなことしていいのか判断できてないですがいちおう動いてはいるみたいです。
stdout/stderr以外を使って、通常のファイルに出力しようとするfprintf()があった場合に、ちゃんとファイル出力できてるか未確認です。
◆.so側に制御が渡ったときのカレントディレクトリ
JavaのコードからJNI(Java Native Interface)を経由してC/C++の.soを呼び出したとき、元のカレントディレクトリが引き継がれるのかと思いきや。
.so呼び出し直後のカレントディレクトリは、ルート「/」でした。
なので、APKのassetsからアプリ専用フォルダにコピーしたデータファイル※をアクセスするためには、そのパスを.so側に教えてあげる必要があります。
※詳細は、前回記事をご参照願います。
JNIの機構では、Java側の関数呼び出しの際に指定した引数が、C側の第3引数以降になるようです。
また、Javaの変数値をCの変数型の値に変換する関数が用意されているとのこと。
解説サイトを参考にMainActivity.javaとnative-lib.cppを以下のように変更しました。
渡されたパスをカレントディレクトリに設定すれば、後はJuliusLibを動作させるための各種データファイルをファイル名だけでアクセスできる・・・ハズ。
この対策をやって、「-C simple_keyword.jconf」と指定した、.jconfはアクセスされるようになりました。
logcat(printf/fprintf)に出力されるエラーメッセージもさほど詳しいものはないことが、この時点で分かった。
なので・・・
概ね
Ⅰ.まずはJavaコードからC関数を呼び出すようなアプリの作り方を調べます。
Ⅱ.Javaコード(Cライブラリ含む)をReact Nativeで使えるパッケージ化方法を調べます。
Ⅲ.React Nativeにパッケージを取り込んで、Build&Go。
の順番で進めてますが、5回目にもなるのに未だⅠの途中です。
前回、AndroidStudioのデバッグ機能を有効に動作させるための設定に1週間程費やしてしまいました。
今回は、その続き。
なんとかデバッグできる環境にはなりましたが、未だ不足している部分があります。
◆標準出力に出るメッセージが見たい
JuliusLib(libjulius&linsent)内で、メッセージ出力にprintf/fprintfが使われています。
「それってAndroid上ではどうなるの?」と調べたら、「logcatに出力される。」という記述をどこぞのサイトを斜めに読んで見つけた。
でも、実際はそんな簡単ではなくて、「だまっててもlogcatに出力される」ようにはなっていませんでした。
「リダイレクトすれば見える」というような記述もあって、その通りやってみた。
----コマンドプロンプト-----------------------------
C:\WINDOWS\system32>cd /d d:\appmake\android/sdk/platform-tools
d:\AppMake\Android\Sdk\platform-tools>adb shell
root@generic_x86:/ # stop
root@generic_x86:/ # setprop log.redirect-stdio true
root@generic_x86:/ # start
root@generic_x86:/ #
---------------------------------------------------
でも、どうも出てるようには見えない。
さらに調べると、なんか色んなことが書いてあって却って面倒そう。
しかたなくJuliusLibのソースに少し付け足しすることに方針転換しました。
プリプロセッサのマクロ定義を使って、printf/fprintfをAndroidのlogcat出力関数に置き換えてみました。
まずは、julius.hの終わりにヘッダファイルの#includeを追加します。
----julius.h---------------------------------------
:
:
/* read libsent includes */
#include <sent/stddefs.h>
:
:
#include <julius/extern.h>
#if defined(__ANDROID__)
# include <julius/print-android-macro.h>
#endif
#endif /* __J_JULIUS_H__ */
---------------------------------------------------
新規追加したヘッダの中身は、こんな感じ。
----print-android-macro.h--------------------------
#include <jni.h>
#include <android/log.h>
#define printf(...) __android_log_print(ANDROID_LOG_INFO, MYTAG, __VA_ARGS__);
#define fprintf(fptr, ...) { \
if(fptr==_STD_OUT){__android_log_print(ANDROID_LOG_INFO, MYTAG, __VA_ARGS__);} \
else if(fptr==_STD_ERR){__android_log_print(ANDROID_LOG_DEBUG, MYTAG, __VA_ARGS__);} \
else {fprintf(fptr, __VA_ARGS__);} \
};
#define MYTAG "JuliusLib"
#define _STD_OUT stdout
#define _STD_ERR stderr
---------------------------------------------------
julius.hと同じフォルダ「(プロジェクト・フォルダ)\app\src\main\cpp\libjulius\include\julius」に追加しました。
ちなみに、マクロ・ヘッダの#includeは「#include <stdio.h>」より前にあるとダメです。
本体の関数定義も置き換えようとしちゃうから。
ちょっと、こんなことしていいのか判断できてないですがいちおう動いてはいるみたいです。
stdout/stderr以外を使って、通常のファイルに出力しようとするfprintf()があった場合に、ちゃんとファイル出力できてるか未確認です。
◆.so側に制御が渡ったときのカレントディレクトリ
JavaのコードからJNI(Java Native Interface)を経由してC/C++の.soを呼び出したとき、元のカレントディレクトリが引き継がれるのかと思いきや。
.so呼び出し直後のカレントディレクトリは、ルート「/」でした。
なので、APKのassetsからアプリ専用フォルダにコピーしたデータファイル※をアクセスするためには、そのパスを.so側に教えてあげる必要があります。
※詳細は、前回記事をご参照願います。
JNIの機構では、Java側の関数呼び出しの際に指定した引数が、C側の第3引数以降になるようです。
また、Javaの変数値をCの変数型の値に変換する関数が用意されているとのこと。
解説サイトを参考にMainActivity.javaとnative-lib.cppを以下のように変更しました。
----MainActivity.java------------------------------
package com.teburarec.call_julius;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import java.io.IOException;
import android.content.res.AssetManager;
import java.io.File;
import java.io.InputStream;
import java.io.FileOutputStream;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
String myDataPath;
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
File myDirObj = getFilesDir();
this.myDataPath = myDirObj.getPath();
Log.d("to dir path", this.myDataPath);
initDataFiles();
setContentView(R.layout.activity_main);
// Example of a call to a native method
TextView tv = findViewById(R.id.sample_text);
String rtmsg = stringFromJNI(this.myDataPath);
tv.setText(rtmsg);
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI(String curpath);
private void initDataFiles() {
AssetManager assetMgr = getResources().getAssets();
try {
byte[] buffer = new byte[4096];
String files[] = assetMgr.list("jdata");
for(int i = 0; i < files.length; i++) {
Log.d("assets file", files[i]);
String assetPath = "jdata/" + files[i];
InputStream infile = assetMgr.open(assetPath);
FileOutputStream outfile = openFileOutput(files[i], MODE_PRIVATE);
int n = 0;
while (-1 != (n = infile.read(buffer))) {
outfile.write(buffer, 0, n);
}
outfile.close();
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
---------------------------------------------------
渡されたパスをカレントディレクトリに設定すれば、後はJuliusLibを動作させるための各種データファイルをファイル名だけでアクセスできる・・・ハズ。
----native-lib.cpp---------------------------------
:
:
extern "C" JNIEXPORT jstring JNICALL
Java_com_teburarec_call_1julius_MainActivity_stringFromJNI(
JNIEnv* env,
jobject jObj /* this */,
jstring curpath) {
const int argc = 3;
const char *argv[] = {"julius-sample", "-C", "simple_keyword.jconf"};
:
:
int ret;
const char *jdataPath = env->GetStringUTFChars(curpath, NULL);
chdir(jdataPath);
env->ReleaseStringUTFChars(curpath, jdataPath);
/* by default, all messages will be output to standard out */
/* to disable output, uncomment below */
//jlog_set_output(NULL);
/* output log to a file */
//FILE *fp; fp = fopen("log.txt", "w"); jlog_set_output(fp);
:
:
---------------------------------------------------
この対策をやって、「-C simple_keyword.jconf」と指定した、.jconfはアクセスされるようになりました。
logcat(printf/fprintf)に出力されるエラーメッセージもさほど詳しいものはないことが、この時点で分かった。
なので・・・
スマフォのアプリを作りたい(28):スマフォだけで動作する音声認識④
プログラミング [2020/07/18]
JuliusをAndroidスマフォ上で動作させたいと思ってます。
概ね
Ⅰ.まずはJavaコードからC関数を呼び出すようなアプリの作り方を調べます。
Ⅱ.Javaコード(Cライブラリ含む)をReact Nativeで使えるパッケージ化方法を調べます。
Ⅲ.React Nativeにパッケージを取り込んで、Build&Go。
の順番かと思ってますが、このサブタイトルで4回目にもなるのですが未だⅠの途中です。
前回、JuliusLib(libjulius&libsent)をAndroidStudioのC++プロジェクト内に持ち込んで、
ビルドして、実行してみるところまでやりました。
とはいっても、肝心な音声認識を確認するところまでは届いてなくて、「起動はした」止まりです。
続きです。
◆JuliusLibの動作のさせかた調査
「ちょっと、移植作業としての順番がおかしくねーか」と言われそうですが、こんな感じです。
提供されているjulius-simple.cをビルドしたバイナリは、dictation-kit-4.5には含まれていないみたい。
実際にPC版とかを動かして確認するのはちょっと面倒そう。
なので、JuliusBookとソース等からJuliusLib&julius-simpleの使い方を調べます。
1)まずはJuliusLibの起動パラメタには何を指定するのか?
julius-simpleのオリジナルコードは起動パラメタをそのままライブラリに渡している。
指定できるパラメタ(オプション)に「-C」があることをライブラリ内のソースから確認しました。
その他は、-AM|-AM_GMM|-LM|-SR|-GLOBAL|-sectioncheck|-nosectioncheck|・・・(※多すぎたので省略)などがありました。
ともかく、-Cで.jconfファイルが指定できれば、上記のその他の動作パラメタは.jconfファイルに記載して指定できるはず。
2)じゃあ、.jconfファイルってどんな?
ディクテーションキット内に00readme-ja.txt(英:00readme.txt)というファイルがあり、その中に仕様が記述されていました。
dictation-kit-4.5\src\julius-4.5\libjulius\00readme-ja.txt
(前記の調べは、このファイルを読めば分かることでした。^^;;)
また、サンプルの.jconfファイルも含まれていた。コメントとしてパラメタの概説も載ってます。
dictation-kit-4.5\main.jconf
これをベースにします。
3)今回Android上で確認したい機能と制約は?
試したいのは個別単語辞書に基づいた単語認識です。
「スマフォのアプリを作りたい(25)」で試した動作をスマフォで確認したい。
「julius.exe -w 個別単語辞書 -h 音響モデル -input mic」と同様のことを試すということです。
ただし、前回のビルド段階で「Juliusが前提としているサウンドシステムは、Android SDK(NDK)標準では含まれていない」ことが分かったので、マイク入力は使えません。
よって、.jconfファイル/個別単語辞書/音響モデル/音声ファイルをAPK含めて、
native-lib.cppでは、argv[]指定を「-C .jconfファイル」※として起動して、単語認識が動作するか確認します。
(※この点は、予想通りなので、native-lib.cppの修正はせずに済みそう・・・?)
4)単語辞書と音声ファイル等を準備する
【単語辞書】
「スマフォのアプリを作りたい(25)」で作った単語辞書は、「読み」の記述の仕方が正しくありませんでした。
例えば、「体操 たいそう」は、「体操 たいそー」にしないといけない。
作り直します。やり方は、「スマフォのアプリを作りたい(25)」に書いてあります。
【音響モデル】
ディクテーションキットに含まれていたjnas-mono-16mix-gid.binhmmを使用させていただきます。
dictation-kit-4.5\model\phone_m\jnas-mono-16mix-gid.binhmm
【音声ファイル】
音声ファイルはwavでいいみたいなので、開発タブレットPCで自分の声を録音して作ります。
と簡単に思って始めたが、結構面倒だった。
まずは、Windowsのサウンドレコーダーでよかろうと思って探したが・・・ない!
Windows10からはボイスレコーダーっていう名前に変わってたのね。
早速、起動してマイク入力して録音してみた。
録音音声はどこに?
ライブラリ>ドキュメント>サウンドレコーディング(C:\Users\(ユーザID)\Documents\サウンド レコーディング)でした。
ファイル拡張子が.m4aです。(.wavでよかったのに。)
サウンドレコーダー自体に.wavで保存する機能は・・・ない!んだよねきっと。
audacityをインストールしてなかったか?・・・ない!
(以前のHDDパンクの折にアンインストールしてしまったようだ。)
再ダウンロード&インストールを実施し、audacity起動して、録音した.m4aを開こうとしたら・・・エラーが出た。
FFmpegというやつが必要なのだそうだ。
FFmpegをダウンロードしてインストール。(最初からaudacityで録音すれば良い話なのだが・・・)
audacityを再起動して、やっと.m4aが開けた。
JuliusBookにあるように、入力音声のタイプとして指定できる属性もあるが、デフォルトでサポートしているのはモノラル/16bit/16000hzのようなので、それに合わせて.wav出力する。
audacityの場合、サンプリングレートの変換はプロジェクトの属性を予め出力するレートに変更しておく必要があるようでした。
【ファイル名リスト】
JuliusBookによると、音声ファイルを入力音源として使用する場合、「-input=rawfile -filelist ファイル名リスト」として指定するみたいです。
なので、ファイル名リストというのも準備します。
単に「音声ファイル名[改行]」の繰り返しのテキストファイルを作成しました。
念のため文字コード指定はUTF-8にしておきました。
【.jconf】
dictation-kit-4.5\main.jconfをコピーして、natibe-lib.cpp内で指定してあった「simple_keyword.jconf」という名前でセーブ。
以下の記述を追加しました。
これで、JuliusLibに必要なデータ(ファイル)類と動作パラメタの指定の仕方がざっくりわかりました。
では、これらをAPKに入れて、プログラムから使わせる方へ話を進めます。
・・・
概ね
Ⅰ.まずはJavaコードからC関数を呼び出すようなアプリの作り方を調べます。
Ⅱ.Javaコード(Cライブラリ含む)をReact Nativeで使えるパッケージ化方法を調べます。
Ⅲ.React Nativeにパッケージを取り込んで、Build&Go。
の順番かと思ってますが、このサブタイトルで4回目にもなるのですが未だⅠの途中です。
前回、JuliusLib(libjulius&libsent)をAndroidStudioのC++プロジェクト内に持ち込んで、
ビルドして、実行してみるところまでやりました。
とはいっても、肝心な音声認識を確認するところまでは届いてなくて、「起動はした」止まりです。
続きです。
◆JuliusLibの動作のさせかた調査
「ちょっと、移植作業としての順番がおかしくねーか」と言われそうですが、こんな感じです。
提供されているjulius-simple.cをビルドしたバイナリは、dictation-kit-4.5には含まれていないみたい。
実際にPC版とかを動かして確認するのはちょっと面倒そう。
なので、JuliusBookとソース等からJuliusLib&julius-simpleの使い方を調べます。
1)まずはJuliusLibの起動パラメタには何を指定するのか?
julius-simpleのオリジナルコードは起動パラメタをそのままライブラリに渡している。
指定できるパラメタ(オプション)に「-C」があることをライブラリ内のソースから確認しました。
その他は、-AM|-AM_GMM|-LM|-SR|-GLOBAL|-sectioncheck|-nosectioncheck|・・・(※多すぎたので省略)などがありました。
ともかく、-Cで.jconfファイルが指定できれば、上記のその他の動作パラメタは.jconfファイルに記載して指定できるはず。
2)じゃあ、.jconfファイルってどんな?
ディクテーションキット内に00readme-ja.txt(英:00readme.txt)というファイルがあり、その中に仕様が記述されていました。
dictation-kit-4.5\src\julius-4.5\libjulius\00readme-ja.txt
(前記の調べは、このファイルを読めば分かることでした。^^;;)
また、サンプルの.jconfファイルも含まれていた。コメントとしてパラメタの概説も載ってます。
dictation-kit-4.5\main.jconf
これをベースにします。
3)今回Android上で確認したい機能と制約は?
試したいのは個別単語辞書に基づいた単語認識です。
「スマフォのアプリを作りたい(25)」で試した動作をスマフォで確認したい。
「julius.exe -w 個別単語辞書 -h 音響モデル -input mic」と同様のことを試すということです。
ただし、前回のビルド段階で「Juliusが前提としているサウンドシステムは、Android SDK(NDK)標準では含まれていない」ことが分かったので、マイク入力は使えません。
よって、.jconfファイル/個別単語辞書/音響モデル/音声ファイルをAPK含めて、
native-lib.cppでは、argv[]指定を「-C .jconfファイル」※として起動して、単語認識が動作するか確認します。
(※この点は、予想通りなので、native-lib.cppの修正はせずに済みそう・・・?)
4)単語辞書と音声ファイル等を準備する
【単語辞書】
「スマフォのアプリを作りたい(25)」で作った単語辞書は、「読み」の記述の仕方が正しくありませんでした。
例えば、「体操 たいそう」は、「体操 たいそー」にしないといけない。
作り直します。やり方は、「スマフォのアプリを作りたい(25)」に書いてあります。
【音響モデル】
ディクテーションキットに含まれていたjnas-mono-16mix-gid.binhmmを使用させていただきます。
dictation-kit-4.5\model\phone_m\jnas-mono-16mix-gid.binhmm
【音声ファイル】
音声ファイルはwavでいいみたいなので、開発タブレットPCで自分の声を録音して作ります。
と簡単に思って始めたが、結構面倒だった。
まずは、Windowsのサウンドレコーダーでよかろうと思って探したが・・・ない!
Windows10からはボイスレコーダーっていう名前に変わってたのね。
早速、起動してマイク入力して録音してみた。
録音音声はどこに?
ライブラリ>ドキュメント>サウンドレコーディング(C:\Users\(ユーザID)\Documents\サウンド レコーディング)でした。
ファイル拡張子が.m4aです。(.wavでよかったのに。)
サウンドレコーダー自体に.wavで保存する機能は・・・ない!んだよねきっと。
audacityをインストールしてなかったか?・・・ない!
(以前のHDDパンクの折にアンインストールしてしまったようだ。)
再ダウンロード&インストールを実施し、audacity起動して、録音した.m4aを開こうとしたら・・・エラーが出た。
FFmpegというやつが必要なのだそうだ。
FFmpegをダウンロードしてインストール。(最初からaudacityで録音すれば良い話なのだが・・・)
audacityを再起動して、やっと.m4aが開けた。
JuliusBookにあるように、入力音声のタイプとして指定できる属性もあるが、デフォルトでサポートしているのはモノラル/16bit/16000hzのようなので、それに合わせて.wav出力する。
audacityの場合、サンプリングレートの変換はプロジェクトの属性を予め出力するレートに変更しておく必要があるようでした。
【ファイル名リスト】
JuliusBookによると、音声ファイルを入力音源として使用する場合、「-input=rawfile -filelist ファイル名リスト」として指定するみたいです。
なので、ファイル名リストというのも準備します。
単に「音声ファイル名[改行]」の繰り返しのテキストファイルを作成しました。
念のため文字コード指定はUTF-8にしておきました。
【.jconf】
dictation-kit-4.5\main.jconfをコピーして、natibe-lib.cpp内で指定してあった「simple_keyword.jconf」という名前でセーブ。
以下の記述を追加しました。
----simple_keyword.jconf---------------------------
:
#!!-C simple_keyword.jconf
:
-input rawfile
:
-filelist invoicename.txt
:
-w teburarecword.dict
:
-h jnas-mono-16mix-gid.binhmm
:
---------------------------------------------------
これで、JuliusLibに必要なデータ(ファイル)類と動作パラメタの指定の仕方がざっくりわかりました。
では、これらをAPKに入れて、プログラムから使わせる方へ話を進めます。
・・・
嬉し恥ずかしお百姓Season2(11):とほほなタネ撒き
園芸 [2020/07/17]
長雨でした。
3週間くらいスッキリしない天気が続いてました。
お陰で、タケノコ採りもフェードアウトしちゃったし、畑仕事もままならない状態が続いてた。
それでなくても日照時間の短い圏なのに。
西の方では災害にまでなった地域もあるから、それくらいでグダグダ言ってられませんね。
被災された地方の方たちには心よりお見舞い申し上げます。
さて、今シーズンの種まき等出だしで躓いた話です。
ど素人なもんだから、若干虫を甘く見てました。
昨年はアスパラ菜を食い荒らされたくらいでしたが、今年は・・・
◆カボチャとオクラ
地撒きすると、芽が出たとたんに虫や鳥に食べられちゃうと思って、5月中に棲家でポットに種まきして少し大きくしてから畑に植え替えようと考えました。
最初はカボチャ。
芽が出て元気なのですが、2、3日すると葉っぱがきれいになくなってます。
あまりに完全に食べられているので、最初鳥を疑って、網を掛けてみました。
でも、やっぱり新芽の段階で、葉がなくなります。
???
鳥が網をかいくぐって食べる?
いやいやそんな器用なことは。
ある朝、日の出とともに見にいって、犯行現場を押さえました。
ナメクジです。
これまでは、見つけても殺虫的なことはせずに、多少不愉快ではありますが、見て見ぬふりをしてました。
でも、お腹のあたりを緑色にしてうろついているのを見て、憎しみがメラメラと燃えました。
とりあえずカボチャは、日当たりの良い方に置き場所を変えて。
それでも、周りを徘徊しているのを見つけたら、棒でつまんで集めて、塩攻めにしてやりました。
でも、結局最初に植えたタネからでた芽はことごとく食べられてしまった。
なので、種の蒔き直し。とほほ。
オクラも、
なかなか芽が出ないなぁと思ってたのですが、こちらは双葉が開く前に食われてたらしく、よく見るとポットの地面スレスレに残った茎も見えてる。
こちらも、置き場所を変えて、もう一回撒きなおし。

お陰で、芽出しで1か月近くロスしてしまった。
カボチャは、芽出しして6月中旬に畑に植え替えた。
◆鷹の爪
ちなみに、カボチャ、オクラ、鷹の爪(唐辛子)は、昨年育てたものの子供。
タネにした分を今年植えました。
唐辛子のタネもポット撒きにしたのですが、芽が出ません。
最初普通の畑の土をポットに入れてタネを撒いたのですが、深過ぎたのかもしれません。
これも、2度撒き。
今度は、買って来てあった種まき用の土を使って、タネの上に薄く土を被せただけにしました。
芽がたーくさん出たので、間引いた分をプランターに植え変えた。
それでも、こんな感じ。

プランターに植え替えた方の置き場所は、ナメクジ出没エリアにした。
カボチャ/オクラがあるうちはタカノツメには手を出さなかったから。
でも・・・食べるものがなくなったせいか、こちらも食べ始めたみたい。
棲家周りが、虫/鳥環境的に安全かと思ったのですが、そうでもないことが判明したので、6月下旬にとっとと畑に植え替えました。
オクラ

タカノツメ

失敗策はまだまだあります。
・・・
3週間くらいスッキリしない天気が続いてました。
お陰で、タケノコ採りもフェードアウトしちゃったし、畑仕事もままならない状態が続いてた。
それでなくても日照時間の短い圏なのに。
西の方では災害にまでなった地域もあるから、それくらいでグダグダ言ってられませんね。
被災された地方の方たちには心よりお見舞い申し上げます。
さて、今シーズンの種まき等出だしで躓いた話です。
ど素人なもんだから、若干虫を甘く見てました。
昨年はアスパラ菜を食い荒らされたくらいでしたが、今年は・・・
◆カボチャとオクラ
地撒きすると、芽が出たとたんに虫や鳥に食べられちゃうと思って、5月中に棲家でポットに種まきして少し大きくしてから畑に植え替えようと考えました。
最初はカボチャ。
芽が出て元気なのですが、2、3日すると葉っぱがきれいになくなってます。
あまりに完全に食べられているので、最初鳥を疑って、網を掛けてみました。
でも、やっぱり新芽の段階で、葉がなくなります。
???
鳥が網をかいくぐって食べる?
いやいやそんな器用なことは。
ある朝、日の出とともに見にいって、犯行現場を押さえました。
ナメクジです。
これまでは、見つけても殺虫的なことはせずに、多少不愉快ではありますが、見て見ぬふりをしてました。
でも、お腹のあたりを緑色にしてうろついているのを見て、憎しみがメラメラと燃えました。
とりあえずカボチャは、日当たりの良い方に置き場所を変えて。
それでも、周りを徘徊しているのを見つけたら、棒でつまんで集めて、塩攻めにしてやりました。
でも、結局最初に植えたタネからでた芽はことごとく食べられてしまった。
なので、種の蒔き直し。とほほ。
オクラも、
なかなか芽が出ないなぁと思ってたのですが、こちらは双葉が開く前に食われてたらしく、よく見るとポットの地面スレスレに残った茎も見えてる。
こちらも、置き場所を変えて、もう一回撒きなおし。

お陰で、芽出しで1か月近くロスしてしまった。
カボチャは、芽出しして6月中旬に畑に植え替えた。
◆鷹の爪
ちなみに、カボチャ、オクラ、鷹の爪(唐辛子)は、昨年育てたものの子供。
タネにした分を今年植えました。
唐辛子のタネもポット撒きにしたのですが、芽が出ません。
最初普通の畑の土をポットに入れてタネを撒いたのですが、深過ぎたのかもしれません。
これも、2度撒き。
今度は、買って来てあった種まき用の土を使って、タネの上に薄く土を被せただけにしました。
芽がたーくさん出たので、間引いた分をプランターに植え変えた。
それでも、こんな感じ。

プランターに植え替えた方の置き場所は、ナメクジ出没エリアにした。
カボチャ/オクラがあるうちはタカノツメには手を出さなかったから。
でも・・・食べるものがなくなったせいか、こちらも食べ始めたみたい。
棲家周りが、虫/鳥環境的に安全かと思ったのですが、そうでもないことが判明したので、6月下旬にとっとと畑に植え替えました。
オクラ

タカノツメ

失敗策はまだまだあります。
・・・
スマフォのアプリを作りたい(27):スマフォだけで動作する音声認識③
プログラミング [2020/07/09]
JuliusをAndroidスマフォ上で動作させたいと思ってます。
概ね
Ⅰ.まずはJavaコードからC関数を呼び出すようなアプリの作り方を調べます。
Ⅱ.Javaコード(Cライブラリ含む)をReact Nativeで使えるパッケージ化方法を調べます。
Ⅲ.React Nativeにパッケージを取り込んで、Build&Go。
の順番かと思ってますが、現状は未だⅠの途中です。
前回、AndroidStudioでC++のプロジェクトを作成して、テンプレートを動作させました。
それと、Juliusのライブラリ使用のサンプルjulius-simple.cをちょっと俯瞰してみました。
その続きです。
◆続:AndroidStudio環境へのJuliusLib移植
前回julius-simple.cを見ていて気になる点が2つほどありました。
※1:標準出力を使っている。→Androidでは?
※2:音声データの入力方法に「バッファ渡し」的なものはない。
※1の件に関しては調べだしたらすぐ解決しました。
Androidでは標準出力はlogcatになっている(標準エラー出力も含む)そう。
訂正:誤報です。標準出力がだまっててもlogcatに出力されるわけではありませんでした。
詳細は次回に記載いたします。m(__)m
「では、MIC入力は?」とも思いますが、
動き出せたら、Juliusがエラー等のメッセージを出力してるでしょうから、きっと対策の糸口は見えるかと。
AndroidStudioのC++テンプレートでのJavaからC関数のコールのところがまだモヤモヤです。
もうちょっと深追いが必要です。
参考:https://qiita.com/ymmtyuhei/items/7109579210af34ec697c
JNI(Java Native Interface):Javaとネイティブコードとのインタフェース仕様のことだそうです。
呼び出し元のJavaでstringFromJNI()とされている関数名が、呼び出し先で酷く長い関数名になっていたのは、この仕様によるもののようです。
native-lib.cppで定義されていた関数名の形式・意味は、以下だそうです。
Java_[呼び出し元のパス(src後のパス&“_”区切り)とファイル名(拡張子なし)]_呼び出し関数名()
なので、stringFromJNI()が
Java_com_teburarec_call_1julius_MainActivity_stringFromJNI()になるわけです。
途中のcall_juliusと言うフォルダがcall_1juliusと表現されているのは、区切り記号としての「_」とフォルダ名中の「_」を区別するためなんだろうなと思います。
では、移植作業を始めましょう。
上記の参考サイトが参考にしている本家サイトの説明を読んでみます。
参考:https://developer.android.com/studio/projects/add-native-code?hl=ja
まずはソースを作成/追加しろと書かれています。
1)JuliusLibのソースの持ち込み
Juliusサイトからダウンロードしてきたディクテーションキットに含まれるソースからコピーします。
dictation-kit-4.5\src\julius-4.5フォルダ下のlibjulius、libsentをフォルダごとAndroidStudioのプロジェクトフォルダにコピーします。
コピー先:(プロジェクトフォルダ)\app\src\main\cpp ・・・・native-lib.cppのあるフォルダ
2)native-lib.cppへのjulius-simple.c内処理のマージ
2-1)julius-simple.c内の「#include ・・・」から内部関数をnative-lib.cppの「#include ・・・」の下にコピペしました。
2-2)julius-simple.c内のmain()の処理コードをcom_teburarec_call_1julius_MainActivity_stringFromJNI()の処理コードにまるっと置き換えました。
この時点で、AndroidStudio側で、native-lib.cppを開くと、自動的に静的解析(って云うんでしょうか)が行われているようで、辻褄の合わない箇所がエラーとして表示されます。(変な箇所が赤字で表示されて、ポインタを載せるとエラーの内容が表示されます。)
まずは、先頭の「#include」で、「そんなパスは存在しない。」と出ます。
なので、それ以降のライブラリのヘッダに含まれる定義(変数、定数、関数)が全部未定義のものというエラーです。
早い話、JuliusLib用のインクルードパスをどっかで指定しないといけないですね。
先の本家ページの次の手順がCMakeを設定しろなので、設定の仕方を調べました。
CMakeの設定は、CMakeList.txtで行うんですね。
native-lib.ccppと同じフォルダ:(プロジェクトフォルダ)\app\src\main\cppにありました。
3)CMakeList.txtの編集
3-1)CMakeList.txtでインクルードパスを指定します。
以下の朱書きの記述を追加しました。
さらに、-Dコンパイルオプションで振り分けされているインクルードファイルがあるらしく、その中で定義されている定数も未定義となっていました。
3-2)CMakeList.txtでコンパイルオプション(-D)を指定する。
以下の記述を追加しました。
4)native-lib.cppの修正
この時点で残ったエラーは、元のjulius-simple.cのmain()からそのままコピペした部分でした。
・引数(argc,argv)の参照がそのままになっている点
→引数の問題は、参照部分削除/固定値の参照に変更
const int argc = 3;
const char *argv[] = {"julius-simple", "-C", "simple_keyword.jconf"};
・char * を指定するべき引数に、const char *を指定していると警告
「jconf = j_config_load_args_new(argc, argv);」を
→「jconf = j_config_load_args_new(argc, (char **) argv);」に変更
「while (get_line_from_stdin(・・・, "enter MFCC filename->") != NULL) {」を
→「while (get_line_from_stdin(・・・, (char *) "enter MFCC filename->") != NULL) {」
・リターンが数値になっている点・・・元のテンプレートは文字列(ポインタ)
→「return env->NewStringUTF("メッセージ");」に変更
としました。
CMakeList.txtで指定したインクルードパスが有効にならなかった件は放置して、本家サイトに書いてある3番目のGladleを設定しろをやってみます。
・・・
概ね
Ⅰ.まずはJavaコードからC関数を呼び出すようなアプリの作り方を調べます。
Ⅱ.Javaコード(Cライブラリ含む)をReact Nativeで使えるパッケージ化方法を調べます。
Ⅲ.React Nativeにパッケージを取り込んで、Build&Go。
の順番かと思ってますが、現状は未だⅠの途中です。
前回、AndroidStudioでC++のプロジェクトを作成して、テンプレートを動作させました。
それと、Juliusのライブラリ使用のサンプルjulius-simple.cをちょっと俯瞰してみました。
その続きです。
◆続:AndroidStudio環境へのJuliusLib移植
前回julius-simple.cを見ていて気になる点が2つほどありました。
※1:標準出力を使っている。→Androidでは?
※2:音声データの入力方法に「バッファ渡し」的なものはない。
※1の件に関しては調べだしたらすぐ解決しました。
Androidでは標準出力はlogcatになっている(標準エラー出力も含む)そう。
訂正:誤報です。標準出力がだまっててもlogcatに出力されるわけではありませんでした。
詳細は次回に記載いたします。m(__)m
「では、MIC入力は?」とも思いますが、
動き出せたら、Juliusがエラー等のメッセージを出力してるでしょうから、きっと対策の糸口は見えるかと。
AndroidStudioのC++テンプレートでのJavaからC関数のコールのところがまだモヤモヤです。
もうちょっと深追いが必要です。
参考:https://qiita.com/ymmtyuhei/items/7109579210af34ec697c
JNI(Java Native Interface):Javaとネイティブコードとのインタフェース仕様のことだそうです。
呼び出し元のJavaでstringFromJNI()とされている関数名が、呼び出し先で酷く長い関数名になっていたのは、この仕様によるもののようです。
native-lib.cppで定義されていた関数名の形式・意味は、以下だそうです。
Java_[呼び出し元のパス(src後のパス&“_”区切り)とファイル名(拡張子なし)]_呼び出し関数名()
なので、stringFromJNI()が
Java_com_teburarec_call_1julius_MainActivity_stringFromJNI()になるわけです。
途中のcall_juliusと言うフォルダがcall_1juliusと表現されているのは、区切り記号としての「_」とフォルダ名中の「_」を区別するためなんだろうなと思います。
では、移植作業を始めましょう。
上記の参考サイトが参考にしている本家サイトの説明を読んでみます。
参考:https://developer.android.com/studio/projects/add-native-code?hl=ja
まずはソースを作成/追加しろと書かれています。
1)JuliusLibのソースの持ち込み
Juliusサイトからダウンロードしてきたディクテーションキットに含まれるソースからコピーします。
dictation-kit-4.5\src\julius-4.5フォルダ下のlibjulius、libsentをフォルダごとAndroidStudioのプロジェクトフォルダにコピーします。
コピー先:(プロジェクトフォルダ)\app\src\main\cpp ・・・・native-lib.cppのあるフォルダ
2)native-lib.cppへのjulius-simple.c内処理のマージ
2-1)julius-simple.c内の「#include ・・・」から内部関数をnative-lib.cppの「#include ・・・」の下にコピペしました。
2-2)julius-simple.c内のmain()の処理コードをcom_teburarec_call_1julius_MainActivity_stringFromJNI()の処理コードにまるっと置き換えました。
この時点で、AndroidStudio側で、native-lib.cppを開くと、自動的に静的解析(って云うんでしょうか)が行われているようで、辻褄の合わない箇所がエラーとして表示されます。(変な箇所が赤字で表示されて、ポインタを載せるとエラーの内容が表示されます。)
まずは、先頭の「#include
なので、それ以降のライブラリのヘッダに含まれる定義(変数、定数、関数)が全部未定義のものというエラーです。
早い話、JuliusLib用のインクルードパスをどっかで指定しないといけないですね。
先の本家ページの次の手順がCMakeを設定しろなので、設定の仕方を調べました。
CMakeの設定は、CMakeList.txtで行うんですね。
native-lib.ccppと同じフォルダ:(プロジェクトフォルダ)\app\src\main\cppにありました。
3)CMakeList.txtの編集
3-1)CMakeList.txtでインクルードパスを指定します。
以下の朱書きの記述を追加しました。
----CMakeList.txt---------------------------------
:
add_library( # Sets the name of the library.
native-lib
:
:
native-lib.cpp )
# インクルードパス指定
target_include_directories( # ターゲット名
native-lib
# Private指定
PRIVATE
# インクルードパス
${CMAKE_CURRENT_SOURCE_DIR}/libjulius/include
${CMAKE_CURRENT_SOURCE_DIR}/libsent/include
)
:
:
---------------------------------------------------
さらに、-Dコンパイルオプションで振り分けされているインクルードファイルがあるらしく、その中で定義されている定数も未定義となっていました。
3-2)CMakeList.txtでコンパイルオプション(-D)を指定する。
以下の記述を追加しました。
----CMakeList.txt---------------------------------
# コンパイル オプション指定
option(__ANDROID__ "for Android" ON)
if(__ANDROID__)
add_definitions(-D__ANDROID__)
endif()
---------------------------------------------------
4)native-lib.cppの修正
この時点で残ったエラーは、元のjulius-simple.cのmain()からそのままコピペした部分でした。
・引数(argc,argv)の参照がそのままになっている点
→引数の問題は、参照部分削除/固定値の参照に変更
const int argc = 3;
const char *argv[] = {"julius-simple", "-C", "simple_keyword.jconf"};
・char * を指定するべき引数に、const char *を指定していると警告
「jconf = j_config_load_args_new(argc, argv);」を
→「jconf = j_config_load_args_new(argc, (char **) argv);」に変更
「while (get_line_from_stdin(・・・, "enter MFCC filename->") != NULL) {」を
→「while (get_line_from_stdin(・・・, (char *) "enter MFCC filename->") != NULL) {」
・リターンが数値になっている点・・・元のテンプレートは文字列(ポインタ)
→「return env->NewStringUTF("メッセージ");」に変更
としました。
-ちょっとハマった:静的解析機能の混沌- これで、ひとまずjulius-simple.cベースのnative-lib.cppのフラグはとれた。・・・かと思いきや。 何回かCMakeList.txtや、ソースコードをAndroidStudioで書き換えてたのですが、最初のころは書き換えた時点でAndroidStudioが新しい内容で再チェックするような動きをしてました。ですが、その内チェックし直さないようになりました。エラーが消えません。その場合は、エラー個所にカーソルを置いて、[Alt]+[Enter]を押すと赤字表示が赤以外に変化して「問題ない」状態を表してました。 さらに、最初にエラーが消えたと思った、「#include ただしこの段階でビルドした場合は、同様のエラー(インクルード・ヘッダが Not Found)にはならなかった。 つまり、Inspection機能(以降、静的解析と呼んじゃいます。)だけの問題のようです。 最初から出てたのかもしれませんが、AndroidStudioの上部に「Unable to execute Clang-Tidy: Cannot create property=Diagnostics for JavaBean=com.jetbrains.cidr.lang.daemon.clang.tidy.ClangTidyYamlLoader...」というエラーが表示されっぱなしです。ClangTidyはコードチェックツールらしいので、修正結果を自動で更新チェックしなくなった件と関係するんでしょうか。 上記したメッセージは放置しても構わないのか?とも思ったのですが、メッセージの後ろに「設定」が行えるリンクが貼られていたので、クリックしてClang-Tidyの有効?チェックを外したらメッセージは消えた。でも正しい処置とは思えない。注1) それでも、静的解析の#includeに絡む警告は消えません。 「Unable to execute・・・」の件を調べましたが、AndroidStudio3.5とNDK r21では互換性がない?とかの書き込みがあって、AndroidStudio4.0では対策されているとありました。調べたら、その条件に当てはまりました。注2) ちょっと身も蓋もない話で俄に信じがたい感じですが、Clang-Tidyのチェックを外したのは正解かも。 Clang-Tidyと切り離して、さらにググりましたが、なかなか解が見つかりません。 そんなこんなしている間に、AndroidStudioを一旦終了(PCの再起動を含む)し、再起動したら・・・ あれ?エラー表示が消えました。何で? 以下の参考サイトを見つけて、能動的に静的解析を実行することを考えていたのですが、肩透かしに会いました。注3) 参考:https://gihyo.jp/dev/serial/01/android_studio/0040 注1)Clang-Tidyを有効に戻す手順は -[File]-[Settings...]選択 -左側リスト欄の「Editor」を展開し、Inspectionsを選択 -右(中)側のリストから「C/C++」を展開 -「Gerenal」-「Clang-Tidy」をチェックし、右下の[OK]をクリック 注2)AndroidStudioのバージョン確認は、メニュー[Help]-[About] NDKのリビジョンの確認手順は -メニュー[Tools]-[SDK Manager]選択 -右側欄の「SDK Tools」タブを選択 -右下の「Show Package Details」をチェック -「NDK(Side by side)」の下でチェックされているのがそれ 注3)Inspectionの実行は、 -[Analyze]-[Isnpect Code...]選択 -チェックする範囲(プロジェクト全体、単独ファイル等)を選択し実行 -[Inspection Result]タブが画面下に作成される |
CMakeList.txtで指定したインクルードパスが有効にならなかった件は放置して、本家サイトに書いてある3番目のGladleを設定しろをやってみます。
・・・