どくぴーの備忘録

真面目なことを書こうとするクソメガネのブログ。いつ投げ捨てられるのかは不明

東京に来ました(就職)

やべぇブログ書いてねぇ

広告に目をやられました。ブログに広告が出っぱなしなのはつらいのでとにかく書いていこうかなと思います。

そういえば大学を卒業していました

いわゆる「17新卒社会人」になりました。明石高専から編入した神戸大学を学部で卒業し、就職して東京に住むことになりました。今は渋谷駅へのアクセスがし易いところ(曖昧)に住んでいます。今後もずっとプログラムを書いていく事になりそうなので当面の目標は 渋谷のイケイケパリピプログラマ です。嘘です。ちゃんと真面目にプログラミングしたいです。

高専から大学に編入した人だと、だいたい大学院への進学が多いような印象があるのですが、僕は色々考えた上で院への進学を諦めました。学力面とかではない…はずです。究極的に言うと

「研究室のM1の先輩方が大学院の授業関連でめちゃくちゃ忙しそうにされていた」

のが決め手でした。大学院に進んだ編入生の同期もなんだかんだ忙しそう。

東京来て変わったこと

  • イベントとかに参加するのに全く苦労しなくなった
    • 地方でイベント、あまりないしやるにしても大変というのはある
  • 人がいっぱいいる
  • 自己管理が大変
    • 体調崩しても頼れる人がいない…
    • 自堕落になると戻れない
  • 食費がやばい
    • ランチで1000円とか飛んで行くのでぐるぐる目になってきた
    • 自炊しないと財布も胃も持たない
  • 休日が家事で溶ける
    • 今日も買い出しと掃除と洗濯と料理してたら一日溶けた
    • ありきたりだけど親のありがたみがすごい

ネタがなくなった

技術的な話をしようと思ったけどここ一ヶ月とても忙しかったせいかまとめられるようなスタックがないのでGW中に何か技術的な記事書きます。

  1. なんでこんな時期にこんなエントリを書いたんだ
  2. 一ヶ月経って落ち着いたのもあるけど一番の理由は 「4月直後だとみんな書いてるし便乗感が出るから」

おまけ

ひとりぐらしはたいへんなので助けてください

http://amzn.asia/7chMyfR

寿司を回そう

この記事は クソアプリ advent calendar 21日目の記事です.遅刻.

qiita.com

クソを作ろう

去年 @amparsand_xyz さんとクソアプリでadvent calendarしたいぞ!ってやってたら現実になってしまったのがことの始まりだった気がします.今年もなんか存在してるので積極的にクソを投下した買ったのですが研究等々で時間が滅亡したのでMAで作った作品の供養をしようと思います.

できたもの

f:id:e10dokup:20161121013108j:plain

hacklog.jp

今年はついに目に見える物に手を出して寿司を回しました.大体のインスピレーションはこちらの記事から得ています

yumulog.hatenablog.com

動いてるシーン

youtu.be

ちゃんと寿司を乗せて回したりもしています

何が起きているのか

「年収が800万円を超えると寿司が止まって見える」「ポリエチレンテレフタレートで覆うことによって『イオン化現象』によって安価に寿司を止める」「寿司と等速で回転することで寿司を止める」「ゾートロープの原理で寿司の可視・不可視を切り替え止まったように見せる」など「動いている寿司を止める」ことを目的とした取り組み(?)はかなり行われていたのですが,「寿司が生み出す不平等」(??)は全く問題視されていないので問題視した結果

「年収っぽいものを診断して高ければ高いほど高速で寿司を回せばいいんじゃね?」

となった結果がこちらです.Androidアプリ上で質問に答えると寿司が回るようになりました.これ以上はありません.ちなみに実装は8時間です.ひどい.

何をやっているのか

f:id:e10dokup:20161221232940p:plain

Raspberry Pi上にsinatraアプリを立てて,そこにAndroidアプリでなんかこう判定した結果をそれっぽく処理して,モータードライバ搭載のArduino互換機「Studuino」をGPIOから信号を送ることで速度を切替えながら回してます.ちなみにGPIOの本数が生える限り回転速度を制御ことが出来ます.

あとMAなのにAPIを一個も使わないのは寂しかったので,株式会社エーアイさんのAITalk Web APIを使って判定結果に応じて琴葉茜ちゃんが関西弁で煽ってくれるようにしました.琴葉姉妹の音源が使えるのはMA限定だったそうです.

おわりに

もっと真面目に時間かけて作ればよかったとおもいました.

来年のMAもガンバルゾー

ニューでなハウス

この記事は denari01 Advent Calendar 2016 - Adventar 16日目の記事です

前日の記事は @sonet_sou くんでした.まだ記事が存在しないので楽しみに待ってます

前置き

当記事はでなりの家に泊まりに行った際の記憶とそこから学ぶ一人暮らしに関する知見を並べたいと思います.ちなみにkosen10sにおけるでなハウスの位置づけは以下のツイートに集約されます.

最初に言っておきたいこと

これからでなりの家に関して色々書きますが,とにかく東京で宿を探すのが大変なので泊めていただけることには大変感謝しております.私も来年は多分上京するので誰かを泊めれるような家の環境を保とうと思います.

ニューでなハウスに泊まりに行かせてもらうことになった

実はでなハウスには2回泊まりに行ったことがある.でなりが福井県にいた頃のオールドでなハウス(以下:オールド)に1回.千葉県に行った後のニューでなハウス(以下:ニュー)に1回だ.ちなみにどちらも「カレーメシを食す会」絡みなので同時に @c_bata_ も泊まったことがあることになる.どうでもいいけど「ニューでなハウス」という文字列からは場末のホテルっぽい響きが感じ取れるので個人的には大好きだ.

オールドにはこれ以降触れないのでこの際説明しておくと,2Kでプロジェクタをおける程度の広さで堂々とカレーメシの調理をすることが可能だった記憶がある.地味に家具もいろいろ揃えていたのでなんだかんだ住みやすそうにはしていたと思う.

なんやかんやあってニューでなハウスに泊めていただくことになった時,でなりは「いやぁうち引っ越したばかりだからやばいよ,なんかにおいするし」とか言っていた記憶があるが当時の僕は「いやまさかそんな限界生活みたいなことしてるはずは無いやろwwwww」とか楽観視していた.

Problem 1 : 布団を買う

当時はまだ立川シネマシティでガルパンの上映が続いていたので,僕はガルパンをみて「いいぞ」ってなりながらニューでなハウスに向かった.最寄り駅につくとでなりが待ってくれていたので

「いやぁ引越し代下げるためにほとんど家具処分したんよ」
「まじ?」

とか話しながら駅からちょっと歩いたところにあるニューでなハウスに到着する.お邪魔してみるとなるほど何もない.どれくらい何もないかというと布団すら無いので一体こいつどこで寝ているんだとかそんな疑問がふつふつと浮かんでいると

「これからクソメガネとカレーメシ先輩(@c_bata_)が寝るための布団買いに行く」

と言い出すので最寄りのニトリに行くことになった.最寄りと言ってもGoogle Maps調べで約2kmの距離があり,それを往復でトボトボ歩いて片道30分らしい.「いや車使えよ」となるのだが免許を持っているのが僕(しかも初心者マーク)だけなので当然のように断念する.行きだけは「はえー,いろいろ店あるねぇ」とか言いながら歩いていたが,ニトリでセミダブルサイズの布団を2つ買って帰ろうとした時に僕たちは気づいてしまった.

「えっ,つらくね…?」

いくら軽めの布団を選んだとは言え,2kmをセミダブルの布団を抱えてトボトボ歩くのは流石に厳しい,しかも梅雨の入りくらいでちょっと蒸し暑くなってきたくらいなので,余計に厳しい.そんなこんなでひぃひぃ言いながら帰りは45分位かけてニューでなハウスにたどり着くことができた.

Problem 2 : 風呂に入る

寝る前にシャワーを浴びようとすると,でなりからファブリーズを渡される.「とりあえずこれで服の臭いを抑えとけ」という意味なのかなと思うと,全然違うって顔をするのでとりあえずはいってみると,これは確かにやばいにおいがする.具体的な言及は避けるが,脱衣所によくある洗濯機置場の排水口からどうやら発生しているみたいなのでそこにファブリーズを散布しろということらしいので言われたとおりにする.なんで洗濯機買ってないんだと思ったが,家の目の前にコインランドリーがあるのでそっちを使うと考えるとまぁ大丈夫だろうという感じがする.40回も使えば減価償却できるんじゃね?という気もしなくもないが,多分突っ込んではいけないのだろう.

シャワーを浴びて出てくると,もう一度臭いが立ち込めているので「うへぇ」という顔をしながらもう一度ファブリーズを散布して急いで服を着て脱出する.他の二人がシャワーを浴びている間に「そういえば排水管って2回曲がっててそこに水が溜まって臭いを防ぐんだったよな」ということに気付いたので,二人に「排水口に水流し込んだら臭い止まるんじゃね?」って言って実際に流し込んでみると無事に臭いは止まった.どうやら溜まってた水がなくなったので臭いがダイレクトに届いていたらしい.あとで聞いてみると「排水管から臭いがするのはずっと人が済んでいない証拠って言われまくった」って言われたので色々と察してしまった.最近もう一度臭いがしたらしく,もう一度水を流し込んだらしい.いやいい加減洗濯機買えよ.

Problem 3 : 単純に住みにくい

梅雨の入りとはいえ,別に空調いれないとやっていけないほど暑いと言うわけでもないはずだったのだが,ニューでなハウスはなぜかとにかく暑かった.空調を仕方ないのでいれさせてもらうと,これがどっこい異様に効かない.後々のでなり曰く「夏は死ぬほど暑くて冬は死ぬほど寒い」ということらしいので単純に断熱的な何かが異様に足りてないのではないかという結論になった.

そしてニューでなハウスでまったりしてると突然「ガタガタガタ…」と揺れたりする.@c_bata_ と二人で「え?地震ですか?」みたいな顔をしているとでなりは「あっ,トラックが通っていますね」みたいなことを言う.家が幹線道路に面しており.トラックとかがバンバン通るため,その影響で家がガタガタと揺れるようだ.本当に地震が来たらあっさり倒壊しそうで冗談抜きで心配している.ちなみにニューでなハウスには謎の隆起があったり,すでに床が斜めになっていたりしているので地震が来なくても倒壊しそうとかは口が裂けても言ってはいけない.

最後に,でなりの住んでいる階にはどうやらネットが配線的に届かないらしく,インターネット環境はなんとWiMAXルータでしのいでいた.しかも別に電波がビンビンに入るわけでもない感じだったのでエンジニアとしては本当に厳しい環境だなと一人で考えていた.

以上より得られた知見

どうやらでなりは家賃に目がくらんでニューでなハウスを選定したようだが,「給料の三分の一を家賃に貢がないと人間的な生活は出来ない」と誰かが言うように本当にケチると限界生活が始まるんだなという感想が得られた.内見していればこんなことにはならないのではないかという気はするが,1-3月期の東京での家探しではそうも言ってられない感じなので不安が止まらない.そして,いくらもったいないとは言え家具は揃えたほうがいい.絶対にQoLに響くので最低限の冷蔵庫,洗濯機,電子レンジくらいは揃えようという気持ちになった.いくら「いやぁ家は寝に帰るだけだし〜」と言っても,そもそもその家が寝るだけで苦しい環境とかだと本当に心が折れかねないので,家探しはまじで大切なんだなとでなりの尊い犠牲からえられたので,これから家を探すにあたって,住みよい家に出会えるように努力をしていきたい.

最後に

ニューでなハウスのことを散々言いましたが,本当に泊めていただいたことには感謝をしております.Thanks a lot for denari's kindness.

叶うならば,でなりがもっといい家に住めますように…

でなlangに見る手を抜いてつくる3文字言語

この記事は denari01 Advent Calendar 2016 - Adventar 5日目の記事です

諸注意

特に何もしてないのでご注意

動機

誰かが「Grassのトークンさえ入れ替えたら任意の3トークンを用いた言語ができるゾ」とか言ってた

まずGrassって何さ

ちょっと草植えときますね型言語 Grass

要は「W」「w」「v」だけで書く言語です.型無しラムダ計算がベースの関数型プログラミング言語ですが特にこれ以降このことに絡んだお話はしません.

やったこと

github.com

まずこちらのyagi.rbを拝借します.こちらを改変するだけです.基本的には「W」「w」「v」のトークンを使いたい任意の3トークンに入れ替えてあげましょう.今回は「で」「な」「り」なので
W -> でw -> なv -> り
ですね.

# W -> で
# w -> な
# v -> り

App = Struct.new(:m, :n)
L = Struct.new(:src)
src = File.read(ARGV[0])
src = src.gsub(/[^でなり]/, "")
# vで区切る,vなし区切りのために更に次で区切る
src = src[/.*\z/m].split(//).map.with_index do |sub, i|
  sub = sub.scan(/+|+/)
  arg_num = sub.first[0] == "" ? sub.shift.size : 0
  sub = sub.each_slice(2).map { |n, m| App[n.size - 1, m.size - 1 ] }
  arg_num.times { sub = [L[sub]] }
  sub
end.flatten(1)

# eval
eval = ->(src, env) do
  ctrue = ->(arg) { eval[[L[[App[2, 1]]]], [arg, ->(arg) { eval[[], [arg]] }]] }
  cfalse = ->(arg) { eval[[L[[]]], [arg]] }
  src.inject(env) do |env, insn|
    val = case insn
    when App
      clos, arg = env[insn.m], env[insn.n]
      case clos
      when Proc then clos[arg]
      when Fixnum then clos == arg ? ctrue : cfalse
      when :out then putc(arg); arg
      when :in then ch = $stdin.getc; ch ? ch.ord : arg
      when :succ then arg.succ & 0xff
      end
    when L
      ->(arg) { eval[insn.src, [arg] + env]}
    end
    [val] + env
  end.first
end

puts "-- denalang source code --"
puts File.read(ARGV[0])
puts "-- result --"
# プリミティブ
eval[[], [eval[[App[0,0]], [eval[src, [:out, :succ, "w".ord, :in]]]]]]
puts "\n"

できた

本当に何もしてないですが,これだけです,早速見てみましょう.じゃあHello World.

$ cat hello.dn
なりななででなでででなりでななななででなでででなででででなでででででなででででででなでででででででなでななななななななななななででででなでででででででなででででででででででででででなでででででででででででななででででででででででななででででででででででででなででででででででででななででででででででででななななななでででででででででででででででなでででででででででででででででででででででなででででででででででででででででででななでででででででででででででででででななでででででででででででででででででなななななででででででででででででででででででででななででででででででででででででででででででででなでででででででででででででででででででででででででななななななななななななななななななななななななななでななななななななななででなななななななでででなななななななででででなでででででななななななななででででででななななななななななななななななでででででででななななななななななななななななななななででででででででななななななななななななななななななななななななななななななななななななでででででででででななななででででででででででなななななななななななでででででででででででなななななななででででででででででででななななななななななななななななななでででででででででででででななななななななななななななななななななななななな
$ ruby denalang_interpreter.rb hello.dn
-- denalang source code --
なりななででなでででなりでななななででなでででなででででなでででででなででででででなでででででででなでななななななななななななででででなでででででででなででででででででででででででなでででででででででででななででででででででででななででででででででででででなででででででででででななででででででででででななななななでででででででででででででででなでででででででででででででででででででででなででででででででででででででででででななでででででででででででででででででななでででででででででででででででででなななななででででででででででででででででででででななででででででででででででででででででででででなでででででででででででででででででででででででででななななななななななななななななななななななななななでななななななななななででなななななななでででなななななななででででなでででででななななななななででででででななななななななななななななななでででででででななななななななななななななななななななででででででででななななななななななななななななななななななななななななななななななななでででででででででななななででででででででででなななななななななななでででででででででででなななななななででででででででででででななななななななななななななななななでででででででででででででななななななななななななななななななななななななな
-- result --
Hello, world!

できました(?)

おわび

Q: え?トークン入れ替えただけだよね?
A: はい,それだけなのに記事書いて申し訳ありませんでした.時間がないけどとりあえず書いた結果がこれです.クソ記事に付き合っていただきありがとうございました

#kosen10s slackでの自分のemojiのつくりかた

これは #kosen10s Advent Calendar 2016 - Adventar の4日目の記事です.

昨日の記事はこちらでした

www.zopfco.de

言い訳

昨日の記事で上がったハードルが高すぎる

技術系アドベントカレンダーに取り上げられたりしてるらしいですが僕は技術の話はしません.ご了承を

kosen10s slack

初日でもなっちゃんid:marin72_com )が言及していましたね

marin72.hatenablog.com

こんな感じでやいのやいのしているわけですが,emojiに関してルータ芸人( id:puhitaku ) も言及したので自分もemojiの話をします.

How to make emoji

自分はMacを使ってるのですが,Macに標準でついてくる「プレビュー.app」がやけに高機能なのでこれを使えば簡単に透過画像を作れます.プレビューのくせに…

画像をもってくる

適当なフリー素材でも探してきましょう.

プレビュー.appで編集する

プレビュー.appで開いて,編集機能を出します.

f:id:e10dokup:20161204104945p:plain

すると出てくるツールバーの中に「インスタントアルファ」があるので,選択しましょう.

f:id:e10dokup:20161204105132p:plain

「インスタントアルファ」は,ドラッグした部分の色合いに近い箇所を全部選択するツールです.ドラッグの長さで選択する領域の微調整も出来ますが,今回は白背景なのでそのまま選択してdeleteキーで全部背景を抜いてしまいます,

後はこれのサイズを縦・横両方128px以下になるようにして,Customize SlackからEmojiに登録しましょう.これで完成です.白背景なら簡単に背景を抜いて透過できるので楽なのですが,アニメのキャプチャなど,空や木がはいって背景が単色ではない画像などでも,うまいことそれぞれの色に合わせてインスタントアルファを描けたり,矩形選択や投げ縄選択を使ったりして微調整しながら比較的簡単に背景を抜くことが出来ます.

ね?簡単でしょ?これで皆も絵文字量産おじさん!

MultiSelectableCalendarなるライブラリを作った

github.com

Androidでカレンダーを操作する必要があったのですが,「この日はOK,この日はNG」みたいな指定の仕方が遷移なしでできるライブラリが無いなぁということになったのでいっそ自作して公開してみました

f:id:e10dokup:20161022015059g:plain

細かいことはリポジトリのREADME.mdを読むとわかるのですが

<dokup.xyz.multiselectablecalendar.ui.MultiSelectableCalenderView
        android:id="@+id/calender"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:monthBackgroundColor="#81D4FA" <!-- color of background parts for month -->
        app:monthTextColor="#546E7A" <!-- color of text for month -->
        app:weekBackgroundColor="#03A9F4" <!-- color of background parts for week -->
        app:weekTextColor="#FFFFFF" <!-- color of text for month -->
        app:dayBackgroundColor="#FFFFFF" <!-- color of background for date -->
        app:dayTextColor="#616161" <!-- color of text for date -->
        app:availableDayBackgroundColor="#FF9800" <!-- color of background for date which is available -->
        app:availableDayTextColor="#FFFFFF" <!-- color of text for date which is available -->
        app:unavailableDayBackgroundColor="#757575" <!-- color of background for date which is unavailable -->
        app:unavailableDayTextColor="#FFFFFF" <!-- color of text for date which is unavailable -->
        app:chevronColor="#1565C0" <!-- color of chevron for month change -->
        />

のようにほとんど全てのパーツについて色指定をできるようにしたり, ScheduleMode というenumを設定することで

  • ScheduleMode.SINGLE
    • OK/NG/特になしを日にちごとにタップすることで設定
    • available -> unavailable -> nothing -> available -> ...
  • ScheduleMode.RANGE
    • A日からB日までタップした範囲の全ての日付をOKにする
    • MultiSelectableCalendarView#setInterval(int interval) によって前後にNGの日にちを設定可能
  • ScheduleMode.DISPLAY
    • 操作不能の表示用モード

というように複数の表示モードを指定したりできるようにしてみました.

カレンダーで設定したOK/NGの日付一覧ですが,

AvailableSchedule schedule = calendarView.getAvailableSchedule // get AvailableSchedule instance
List<Calendar> available = schedule.getAvailableCalendarList(); // get available date as java.util.Calendar's list
List<Calendar> unavailable = schedule.getUnavailableCalendarList(); // get unavailable date as java.util.Calendar's list

のようにすることで java.util.Calendar のListとして取得できます.また MultiSelectableCalendarView#setOnScheduleChangedListener(OnScheduleChangedListener listener) のcallbackでも取得できます.

勉強になったこと

  • custom viewの実装
  • werckerによるデプロイまでのCI
    • 昨日やっとデプロイできるようになりました.というのもdocker imageを作れるだけのストレージに余裕がなかったので研究室のPCを借りてdocker hubにimageをpushするという()

PR/issueや「こここうした方がいいんじゃね」みたいな意見でもなんでもいいのでいただけると泣いて喜ぶと思うのでお願いします

くそおまけ

記事を書いている間に年齢がインクリメントしました.

https://www.amazon.co.jp/gp/registry/wishlist/22SFRRHYUCWKL

Raspberry PiとBluetoothスピーカーとRuby + Sinatraで天の声APIを作ってみる

最近,研究室でRaspberry Piを借りてきたのでせっかくだから喋らせてみることにしました

なんかもうあった

nwpct1.hatenablog.com

カレーメシ先輩( id:nwpct1 )がラズパイ内で音声合成して喋らせていたのでコレを参考にしてみようと思ったのですが,docomo developer supportにはいっているHOYAサービスの音声合成APIを使ってRESTで殴って生成済み音声データを持って来て再生する仕組みにしておうちの中でPOSTすると喋らせてみることにします.

dev.smt.docomo.ne.jp

用意するもの

docomo developer supportに登録

dev.smt.docomo.ne.jp

にアクセスしてアカウントを取得します.取得したら,マイページからAPI利用申請・管理にアクセスしてアプリケーションを登録します.基本情報を入力し,『音声合成 【Powerd by HOYAサービス】』を選択してAPIキーを取得しましょう.

APIエンドポイントを作る

まずはGemfileの定義から.

source "https://rubygems.org"

gem 'sinatra'
gem 'sinatra-contrib'

ただ喋らせるだけなのでこれで十分です.DB用意したりして工夫する際は適宜追加しましょう.完了したら bundle install --path /vender/bundle でインストールします.

app.rb にエンドポイントを定義します.今回は適当に /api/v1/speech とします.ついでに /api/v1/speech/test にテスト用のエンドポイントも用意します.

#!/usr/bin/env ruby
# coding:utf-8
require 'sinatra'
require 'sinatra/json'
require 'json'

require './speech.rb'

# API

get '/api/v1/speech/test' do
  speech = Speech.new
  data = {result: speech.do_speech("これはテストです.音量などを確認してください.")}
  if data[:result] == 'success' then
    status 200
  else
    status 400
  end
  json data
end

post '/api/v1/speech', provides: :json do
  params = JSON.parse(request.body.read,  {:symbolize_names => true})
  text = params[:text]
  speech = Speech.new
  data = {result: speech.do_speech(text)}
  if data[:result] == 'success' then
    status 200
  else
    status 400
  end
  json data
end

実際に喋らせるSpeechクラスを実装します.do_speech メソッドだけですが.

require 'net/http'
require 'uri'

API_KEY = '(docomo developer supportで取得したAPIキー)'

class Speech
  def do_speech(text)

    endpoint = URI.parse('https://api.apigw.smt.docomo.ne.jp/voiceText/v1/textToSpeech')
    endpoint.query = 'APIKEY=' + API_KEY

    request_body = {
        'text'=>text,
        'speaker'=>'hikari'
    }

    res = Net::HTTP.post_form(endpoint, request_body)

    case res
      when Net::HTTPSuccess
        file_name = "voice.wav"
        File.binwrite(file_name, res.body)
        `aplay voice.wav` #Macに喋らせたいときはafplayにしましょう
        File.delete(file_name)
        return "success"
      else
        return res.body
    end
  end
end

ちなみに上のコメントにあるようにaplayをafplayにするとmacで喋れるようになります.この時点で,とりあえず bundle exec ruby app.rb -o 0.0.0.0 で起動して localhost:4567/api/v1/speech

{
    "text": "ほげほげ"
}

みたいなJSONをPOSTするとPCが喋ると思います.

Raspberry Pi側の環境構築

とりあえず頑張ってRaspberry Pirubyをインストールします.

qiita.com

Raspberry Piなのでインストールには凄い時間がかかりますが気長に待ちましょう.

完了したら

gem install bundler

でbundlerをインストールします.完了したらさっきのsinatraアプリケーションをgitなりでRaspberry Pi上に移動して bundle install --path /vender/bundle して, bundle exec ruby app.rb -o 0.0.0.0 で起動します.この時点で,Raspberry Piのイヤホンジャックにイヤホン等を繋いで '(Raspberry PiのIP):4567/api/v1/speech' に先程のJSONをPOSTすると喋るのですが,今回はBluetoothスピーカーに喋らせるので

apt-get install bluetooth bluez bluez-tools pulseaudio pulseaudio-module-bluetooth

でbluezとpulseaudioをインストールします.インストールしたら pulseaudio --start でpulseaudioを起動します.終了は pulseaudio -k です.

続いて,Bluetoothスピーカーの電源を入れ,bluetoothctlでペアリングを行います.

$ bluetoothctl -a
[bluetooth]# power on  //パワーオン
[bluetooth]# scan on   //スキャン開始
[NEW] Device A0:E9:xx:xx:xx:xx BT Speaker name  // Bluetoothスピーカーを見つける
[bluetooth]# connect A0:E9:xx:xx:xx:xx    
[bluetooth]# trust A0:E9:xx:xx:xx:xx
[bluetooth]# exit

ペアリングが完了したらデフォルトをそのスピーカーに設定して

$ pacmd set-default-sink bluez_sink.A0_E9_xx_xx_xx_xx

音量を設定します,

$ pactl set-sink-volume bluez_sink.A0_E9_xx_xx_xx_xx 60%
または
$ alsamixer

これで,Raspberry PiAPIを叩くとBluetoothスピーカーからおもむろに声が鳴り響くと思います.天井付近に設置すれば天の声っぽくなる…か?

サンプルコード

github.com