いろいろ備忘録

雑記です。

アゲアゲ☆将棋実況チャンネルのおすすめ動画

筆者はウォーズ1級の素人です。

見当違いのことを言っていたらコメントで教えていただけると幸いです。

 

念のため、アゲアゲ氏を知らない方のためにアゲアゲ氏がどんな人か説明しますと、アゲアゲ☆将棋実況チャンネルの投稿者であるアゲアゲ氏は奨励会3段というプロ棋士一歩手前まで上り詰めた方です。
最近は全国アマチュア王将位大会で準優勝されるなどアマ棋士として輝かしい成績を収められています。
私たちはそんな偉い方の実況や解説が観られる素晴らしい時代にいます。
観ましょう。

 

では、まずは将棋の動画から。

この対局の前に10分切れ負けを指していたアゲアゲ氏は、10切れを指しているつもりでした。
持ち時間が残り1分20秒、相手との持ち時間の差が1分以上になったところで、ようやく今自分が指しているのが3切れだということに気づきます。うっかりさんですね。

王手を防ぐ香打ちや打ち歩詰めの回避など、格の違いを思い知らされました。

 

次です。

残りの持ち時間がたった10秒にも関わらず、「詰ます」と宣言するアゲアゲ氏に痺れます。

将棋が強いのはもちろんですが、マウスさばきも速いです。


将棋ウォーズ 3切れ実況(492)石田流三間飛車VS左美濃

 

次です。

将棋系YouTuberの筆頭であるクロノ氏主催の将棋系YouTuber大会に出場しなかったアゲアゲ氏ですが、たまたまはく氏(将棋系YouTuber)とマッチングしました。

その時のはく氏視点での動画です。もちろんアゲアゲ氏の実況動画もあります。

静かに甚振られる恐怖を対局者視点で体験できます。


奇跡のマッチング!?VSアゲアゲさん【将棋ウォーズ】

 

ここからは将棋以外の動画です。

突如として始まったこのアゲラジ。

この頃は対局よりもアゲラジが楽しみになっていて、投稿されたらまず最後まで飛ばしてアゲラジの有無を確認していました。

将棋に関する話から冷凍パスタにハマった話まで聞けます。アゲアゲ氏と仲良くなった気分になれます。勝手に。

アゲアゲラジオあり動画 - YouTube

 

次です。

おそらく、アゲアゲ氏は世界で初めて牛角感想戦をした人です。

コメント欄の大喜利も含めて好きです。


牛角感想戦

 

いかがでしたか?

多すぎて書ききれなかったのですが、他にもボイスロイドによる将棋実況、英語将棋実況、棋士の手つきモノマネなど独創的な動画が沢山あります。

全て観て再生回数をアゲアゲしていきましょう。

PocketSphinxをAndroidで使う

親切なチュートリアルがあります。

cmusphinx.github.io

 

自分がやった手順を書きます。

1.サンプルプロジェクトからAARファイル、en-us-ptm(音響モデル)、cmudict-en-us.dict(辞書ファイル)などを取り出しておきます。

2.

AARファイルを読み込みます。

Android AAR形式ライブラリ作成 - ツテなしフリーランス日誌 こちらのAARの使用の1-6までを行います。

3.

app/build.gradleに以下のAntスクリプトを追記します。

ant.importBuild 'assets.xml'
preBuild.dependsOn(list, checksum)
clean.dependsOn(clean_assets)

4.app/src/mainにassetsディレクトリ、その直下にsyncディレクトリを作り、取り出した音響モデルや辞書ファイルを置きます。

5.AndroidManifest.xmlに権限を追記します。

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />

6.PocketSphinxActivityの中を必要な分だけコピペしてきます。

PocketSphinxを「無理やり」日本語で使う

やりたかったこと

Androidアプリをスマートスピーカーのように「こんにちは」という音声を認識したら何か処理を始めるようにする。

音声認識にPocketSphinxを選んだ理由

トリガーとなる音声を認識するために連続音声認識をする必要がありますが、Android組込のSpeechRecognizerや、精度が高いGoogle Cloud Speech APIなどは時間制限がありました。ので音声認識エンジンを別途組み込む事にしました。

PocketSphinxとは、フリーの音声認識エンジンです。
音声モデルが英語のものしかないため、本来は日本語には使えません。Juliusが日本語に対応しているので、一般的にはそちらが使われます。

しかしJuliusはネットワークから使用するには、ADINNETで音声を送信して結果は別で受取り...など面倒な事が多く、また、Androidに組み込むのも手軽にはいかなさそうでした。更にリファレンスを読み解くには多くの予備知識が必要そうです。

一方、PocketSphinxは公式がAndroidのサンプルを公開しており、気軽に実行できました。書かなければならないコードも分かりやすいです。

「無理やり」日本語を認識させるためにやったこと

PocketSphinxは単語と発音記号の対応をdictファイルから読み込みます。

 hello HH AH L OW

日本語の発音→英語の発音をそれらしく書き換えてdictファイルに追加します。

konnichiwa K OW N N IY CH IY W AA

うまく認識されない場合は、konnichiwa(1)のように他の発音を追加するか、しきい値を上げます。

 

okhttp3のwebsocketでのサブプロトコル定義

クライアントは、WebSocketコネクション確立時に、対応可能なサブプロトコル一覧をSec-WebSocket-Protocolヘッダで提示します。

OkHttpではRequestクラスでヘッダを追加出来ます。

そのClientが送るリクエスト全てまたは条件を満たすものに追加したいならInterceptorを使用しましょう。

今回のケースではWebSocketでのrequestはひとつだったので使いませんでした。

サブプロトコル名はアプリケーション側で勝手に決めて大丈夫なものなので、各自サーバが対応する適切なものに変えましょう。

Interceptorを使用しないとき

Request request = new Request.Builder()
.addHeader("Sec-WebSocket-Protocol", "test")
.url(WS_URL)
.build();

Interceptorを使用するとき

Interceptor interceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request req = chain.request()
.newBuilder()
.addHeader("Sec-WebSocket-Protocol", "test")
.build();
return chain.proceed(req);
}
};

OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.build();

 

 ビッグエンディアンからリトルエンディアンに変換

google cloud speech APIを使用するときに書きました。

サンプルで使用されているLINEAR16はPCM16のリトルエンディアン版みたいです。

PCM16は16bit=2byteなので、bytes[i+1] bytes[i]に変換していく作業です。

short型でのコードはこちら。

public static byte[] short2little(short[] sData) {
ByteBuffer buffer = ByteBuffer.allocate(sData.length * 2);
buffer.order(ByteOrder.LITTLE_ENDIAN);
buffer.asShortBuffer().put(sData);
return buffer.array();
}

 

onClosed vs onClosing in OkHttp3のWebSocketクラス

【結論】

onClosing()は成功でも失敗でもとりあえず実行される。

onClosed()は切断が成功した場合実行される。向こう側から一方的に閉じられた場合は実行されない。

順序はonClosing()の後にonClosed()

続きを読む

データバインディングでOrmaとRecyclerView

Ormaの公式のexampleを再現する形でやっていきます。

Ormaは入っていて、モデルを作ってビルドした後という前提です。

exampleではTodoモデルなので、適宜使用するモデルに変更しましょう。 

 

1.build.gradleにバインディング設定を追記。CardViewとRecyclerViewも書いておく。

Android Databinding 〜超入門〜 - Qiita

implementation 'com.android.support:recyclerview-v7:26.1.0'
implementation 'com.android.support:cardview-v7:26.1.0'


2.フラグメントを作成し、xmlのルートをFrameLayoutからlayoutに変更し、ルートのwidthとheight属性、TextViewも消す。RecyclerViewを足す。

参考:

Android-Orma/fragment_recycler_view.xml at master · maskarade/Android-Orma · GitHub

<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="com.example.android.プロジェクト名.なんたらFragment">

<android.support.v7.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#eee"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
/>

</layout>

 

3.公式を参考にFragmentのjavaの方の必要なさそうなソースを消しておく。

Android-Orma/RecyclerViewFragment.java at master · maskarade/Android-Orma · GitHub

 

4.CardViewのXMLをlayoutディレクトリに作成する。

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/tools"
>
<data>
<variable name="user" type="com.example.android.パッケージ名.infra.entity.User" />
</data>
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="4dp"
android:foreground="?android:attr/selectableItemBackground"
card_view:cardCornerRadius="2dp"
card_view:cardElevation="2dp"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
android:text="@{user.name}"
/>
</android.support.v7.widget.CardView>
</layout>

 

5.VH、Adapterの順にコピペしてくる。

Android-Orma/RecyclerViewFragment.java at master · maskarade/Android-Orma · GitHub

6.onCreateViewをいい感じにする。

7.Activityに作ったフラグメントを紐付ける。

このとき、Fragment側で継承しているフラグメントがサポートライブラリならgetSupportFragmentManager()を使用しないとaddが解決出来ない。

 

以上です。

getItemCount()などでUIスレッドからOrmaを利用するため、OrmaDatabaseの生成時に実行スレッドの制約をしていると落ちるので気をつけてください。

 

制約を外すよりもっといいやり方があったら教えてくれると幸いです。