mp3 ファイルが音飛びする話 ( Windows Media Player と Exact Audio Copy )

前回、『RPi3 の mpd で 結構音飛びする mp3 ファイルがあります。自前で入れた Raspbian と Mooreさんでちゃんと比較したわけでは無いのですが、 音飛びはちょっとなぁ... 』なんてことを言ってたりしたんですが...

結局 そのファイルを、RPi3 で動いている moode さんで再生させても、Windows Media Player で直接 mp3 ファイルを再生させても、きっちり同じ場所(時間)同じように音飛びすることが分かって、つまりは mp3 ファイル自体が不良 ということが分かりました。ははは。

ちなみに、『 結構音飛びする mp3 ファイルがあります。』ってところ、不明瞭なわけですが、もうちょっと説明すると『1曲のなかで特定の場所(時間)で音飛びのように聞こえる場所がある mp3 ファイルが、相当数ある』です。つまりおかしな mp3 ファイルがそこそこあるってことでした。

ただ、今までためてた mp3 ファイルで、そういう事思ったことなかったんです。

ごく最近になって『なんか mp3 の音が飛ぶなぁ』って思ってたんです。で、『きっと開発中の飛騨茉莉のせいか、mpdのセッティングのせいかだろう。』なんて思ってたんです。

ですが、私は昨日まで、mp3へのリッピングを Win10 の Windows Media Player でやってました。

本日、その Windows Media Player が犯人であることを突き止めました!

だって、CD から Windows Media Player で mp3 にして、その mp3 を Windows Media Player で聞いてみたら、飛ぶんだもん...。信じられなかったよ~。

昔っからWMPで CD から mp3 作ってて、音飛びなんてそんなに意識したことは無かったんです。たまぁ~に、『一瞬歪むなぁ...』なんて曲があったりはしたのですが、仕方ないかな~。なんて思ってたんです。

お前だったのか....

しかも何回もテストしていると、10曲に1回くらい。しかもランダムで起こったりしてるよーで、頻度高すぎだなぁと。何が変わったのか?昔からなのか?うーんわかりません。

仕方ないので、選手交代です。

Exact Audio Copy

www.exactaudiocopy.de

というソフトがよさそうとのことで、早速ダウンロードして使ってみました。

うーん。ちょっと玄関の敷居が高い感じで、なんというか素人さんにゃちょっとわけわからん部分があるかな。私もなんか最初はとっつきにくかったです。

よそ様ですが、懇切丁寧な使い方の説明をされている所もありますが...それでもとっつきにくい気がします。

が、わかってきたり慣れてくると、 これは良いです。

使い方なんかは、他にゆずるとして、私が思った Windows Media Player に対しするアドバンテージを書いてみましょう。

  • CD から wave データを正確に作る。
    • まぁ、あたりまえっちゃ当たり前なのでしょーけど、そのために必要な色々なパラメーターがあって、かなりマニアックな作りになってます。(そーまでせんと正確な waveファイルって作れんものなのかなぁと思っちゃうくらいです。)
  • wave データを引っこ抜いた後、 mp3 への変換は外部プログラム( lame3 ) を使う。
    • ステキ。何やっているのか明確。安心感大!
  • 選べるCDDB
    • ステキ。ジャケ画像もとれる。(ちょっと怪しい部分ある。そのジャケ画って...ゴホン)
  • ID3タグで、v1 タグ無し、v2 UTF16 を強制できる。
    • 一番うれしい。ちょっと設定調整する必要あります。Windows Media Playerリッピングしたmp3 だと、MPD で文字化けしてたんです。で、別途 mp3tag というソフトで、タグのリライトをやってたんです。ところがこのソフト使えばそういう手間なしに文字化けしなくなりました。やったぜ!

ってなところです。

正直、今ある CD をぜーんぶリッピングしなおしたくなりました。時間があればね....

まだ全部確認してませんがちょっと聞いてみた感じでは音飛びは皆無です。心なしか音が良くなった気さえします。(いや本当はクソミミなので、たぶん気のせいでしょうね。)

いいソフトに出会えました。 Windows Media Player はプレーヤーに専念してもらいましょう。

MPDとRustとRaspberryPiで遊んでみる9 飛騨茉莉

え~、今日はネタは二つ

まず、MPDのフロントエンドを作ろうというプロジェクト『飛騨茉莉』ですが、なんか進んだり戻ったりしています。

というのも、RPi3 でさぁ動かそうと思って、RPi3 で $ cargo run としたら、なんと初回ビルドに10数分かかる! おっそい。遅すぎるぞぉ~

しかも動き出したら、今度は結構CPUをもっていってしまう。だいたい CPU使用率 80% くらい。ちょっと重すぎる。ロードアベレージ的には 1未満だけど、いくら何でもなぁ。 相方の mpd サンは、10% 未満で動いているのでかなり差がある。うーん。

FFT やっているので多少は CPU使うだろうとは思っていたのですが、それほど使うとなるとちょっと開発コンセプトをミスったかしらと思ってしまいました。

Rust って、そんなに重いのか? 作りが悪いのか? 止めるか?

で、 もうちょっとカリカリにしたいと思ったとき、actix-web はなんか触りにくい。tokio ランタイムとの関係性が分かりにくいことと、actix のコンセプトが色々なものを隠していることが気に入らない。actix-web をやめてもちょっとシンプルなフレームワークを使おう。なんて考えが沸々とわいてきまして、こりゃもーやるしかないと...

で、actix-web 捨てて、別のwebサーバーフレームワークにしました。ははは。

wrap というのを知りまして、下層の hyperに対して比較的薄いかぶせ具合のライブラリとなっています。また wrap も hyper も tokio ランタイムを変に被せず普通に使っているので、hyper と tokio の ドキュメントやサンプルがそのまま使えます。なんかよさそう。

結構それなりにまで動くようになった状態だったのですが、一気にぶっ壊して、wrap で建て直しました。いやぁ大変でした。

やっぱりフレームワークというのは、それなりに実装方法を強制してくるわけですので、ほとんど似たよーな事をするにしても全然違うコードが必要となります。あっちではこーなのに、こっちではあーだ。の連続。またそれぞれの個性みたいなものに合わせる必要があるわけで旧来のコードではダメ部分は総とっかえです。

ただ先ほどの言ったように、最下層となる tokio ランタイムがそのまま使えるのは大きかったです。async/await 絡みの部分に対する理解も深まりましたし、実装もいい感じになりました。actix-web を使っていたころよりもコードがシンプルで分かりやすく自由度も高い感じです。websocket もちゃんと行けました。

プロダクト自体もだいたい元の動作が全部動くようになり、ほっと一安心。何とかなってよかった。

しかし、プログラム効率が多少良くなったりしたところで、負荷がそんなに変わるもんでもありません。相変わらず重いわけです。とほほ

RPi3 ってそんなに非力なのか.... RPi4 にすべきか...

などと思ってたのですが、母艦の CentOS8 で開発しているときもちょっと思ってたのですが、Rustで作ったものってよそ様で宣伝されているほど早く無い感じがずーっとしてたんです。なんとなくもちょっとキビキビと動いてほしいのに、スクリプト系で作ったもの見たいに、もっさり感があったんです。CentOS8 でうごかすと、CPU使用率10%ちょっと割るくらいで動くんですが、それでもなんかちょっと高いなぁと...

そこで何気に、リリースビルドを作って動かしてみたんです。

top コマンド使いながら、多少は CPU使用率下がるのかなぁと眺めてました。

ん?でてこん。動いてないのかな?普段なら一番上にくるのになぁ....。いや動いてるぞ。あれ?

そうです。CPU使用率が一気に 1% 未満になったのです。えぇぇぇ~。ちょー軽くなりました。

なんだそれはと思い、armv7 用のリリースビルドをこさえて、RPi3 にもっていってみました。で動かすと、CPU使用率が 5 ~ 12% 位に収まります。相方の mpd サンより、ちょっと重いくらい。ロードアベレージも十分低いです。やった!これならいける!

でも、なんかちょっと rust に振り回された感があったのでちゃんとテストしてみました。(これが二つ目のネタです)

github.com

適当な重い処理として FFTを実行してCPUを使うようなプログラムを作ってみました。でこれ自体のコンパイル時間と、これの実行速度を、デバッグビルト・リリースビルド別に計測してみました。また母艦と RPi3 とでも比べてみました。

母艦と RPi3 の性能差も、8~10倍くらい違ってました。んまぁこれはそんなもんかなとは思っていましたので全然不思議じゃなかったです。

ですが、リリースビルドは、デバッグビルトの10倍以上のスピードで動きます。なにそれ!差がありすぎじゃない? C/C++ とかだと、1.5 ~3倍くらいしか差がなかったよーな気がしてたのです。この認識が間違ってるのかもしれませんが、 10倍ってかなりショックでした。

というより、今までほとんど ログデバッグで済ませててデバッガとか使ったりしてなかったので、デバッグビルトである必要がほとんどなかったわけです。というより、mpd の fifo 食べて FFT してブラウザにデータ送るって処理の部分は音楽の再生に合わせた動作となるので、デバッガで止めながらやるってわけにもいかないですからねぇ。どーしてもってならデバッガ使おうと思ってたんですが、いまんところそこまでではなかったわけです。こんなことならば、最初っから リリースビルドつかってればよかった!

ちなみに、ビルド速度に関しては、デバッグビルトに対してリリースビルドは、おおよそ 1.5倍の時間がかかります。ただ普段はcargo clean なんてしないので作業時間にはそこまで影響しないです。cargo check が爆速なのでコード中は、cargo checkだけで進めてビルドを行わないようにするスタイルになってきているのでなおさらです。cargo watchも使ってますよ。

そもそも、10倍も処理スピード違うと、デバッグビルトの意味が薄くなりそーですよね。(そーいうもんなのかなぁ?)

んまぁ、あらためて Rust のそういうところ勉強させてもらったわけですが、はぁぁぁ。疲れるぅ。

『飛騨茉莉』開発に関しては、あと2つほど山があって、まだまだ疲れそーです。

  • Bluethooth 入力を手作業でやってみたんです。bluez と bluealsa と mpd の組み合わせです。うまく鳴るのですが、bluez側でコネクションを切ると、mpdがコアダンプするんです。たぶん携帯側から Bluethooth 切断しても、同じようにおっこっちゃいそーだなぁ...(まだ試してない)
  • Bluethooth 出力ですが、Moodeさんはかなり強引な方法でやっているよーです。mpdの設定ファイル書き換えて mpd リブートしてます。outputデバイスを動的に追加する方法が無いので、それしか方法なさそうですが...
  • RPi3 の mpd で 結構音飛びする mp3 ファイルがあります。自前で入れた Raspbian と Mooreさんでちゃんと比較したわけでは無いのですが、音飛びはちょっとなぁ...

課題をメモしてみました。なんか大変そうだぁ。

フォントの話 RictyDiminished 亜種

昨日、Ricty の生成スクリプトで、Inconsolata と MigMix を掛け合わせたフォントを作成した話を書きました。

これにより半角文字の太さが、ExtraLight, Light, Reguler から選べるようになったのですが、全角文字の太さは同じなので、ちょっと違和感がありました。

本家の RictyDiminished では、Inconsolata と Circle M+ 1m の組み合わせとなっています。

プログラミング用フォント Ricty Diminished

GitHub - edihbrandon/RictyDiminished: Ricty Diminished --- fonts for programming

Circle M+ 1m は以下にあります

https://mix-mplus-ipa.osdn.jp/mplus/

この Circle M+ 1m ですが、太さが5種類あって Inconsolata とつり合いが取れそうです。 また私的には、濁点・半濁点が強調された、 Circle M+ 1m より、自然な感じの Circle M+ 2m がよさそうに見えましたので、Circle M+ 2m を使ってみようと思います。

RictyDiminished 亜種 を作る

まずは、こちらの先生ページ の内容をおさらいします。 感謝!

で、手順をまとめます。

  1. ubuntu を準備する。(私は ubuntu 20.10 でやりました。)
  2. 最低限必要なものをインストールする apt-get update; apt-get install wget unzip fontforge fonttools;
  3. フォントと、ricty_generator.sh をダウンロードする
  4. ricty_generator.sh を実行する
  5. 幅の確認をする。
  6. 幅の調整をする。

となります。

3 に関してはこんな感じです。ダウンロード

wget -O Inconsolata.zip https://fonts.google.com/download?family=Inconsolata
wget -O clamp-2m-20200415.zip "https://ja.osdn.net/frs/redir.php?m=ymu&f=mix-mplus-ipa%2F72749%2Fclamp-2m-20200415.zip"

unzip Inconsolata.zip
unzip clamp-2m-20200415.zip

wget https://rictyfonts.github.io/files/ricty_generator.sh

4 はこんな感じです。

sh ./ricty_generator.sh -d "<>:*+-0r7DZz\"\`" -n -zuntan-iel_cw1_ static/Inconsolata-{ExtraLight,Regular}.ttf clamp-2m-20200415/clamp-2m-w1-{regular,bold}.ttf
sh ./ricty_generator.sh -d "<>:*+-0r7DZz\"\`" -n -zuntan-il_cw3_  static/Inconsolata-{Light,Regular}.ttf      clamp-2m-20200415/clamp-2m-w3-{regular,bold}.ttf
sh ./ricty_generator.sh -d "<>:*+-0r7DZz\"\`" -n -zuntan-ir_cw4_  static/Inconsolata-{Regular,Bold}.ttf       clamp-2m-20200415/clamp-2m-w4-{regular,bold}.ttf

5 は、

for P in static/Inconsolata-*.ttf clamp-2m-20200415/clamp-2m-*.ttf Ricty*.ttf; do
   ttx -t OS/2 "$P"
done

grep xAvgCharWidth static/*ttx clamp-2m-20200415/*ttx clamp-2m-20200415/*ttx Ricty*.ttx

を実行して、xAvgCharWidth の値を見ます。6 のスクリプトの値に反映させます。

6

for P in Ricty*.ttf; do
    ttx -t OS/2 "$P"
    sed -i.bak -e 's,xAvgCharWidth value="897",xAvgCharWidth value="505",' "${P%%.ttf}.ttx"
    mv "$P" "${P%%.ttf}.ttf.orig"
    ttx -m "${P%%.ttf}.ttf.orig" "${P%%.ttf}.ttx"
done

# rm *ttx *bak *ttf.orig

RictyDiminished 亜種 を使う

作ったフォントをインストールして使ってみました。いずれも 16pt です。エディタで使うには大き目かもしれませんね。

  • Inconsolata Reguler + clamp-2m-w4-regular の Discode

f:id:zuntansan:20200705144520p:plain

f:id:zuntansan:20200705144537p:plain

  • Inconsolata ExtraLightLight + clamp-2m-w1-regula の Discode

f:id:zuntansan:20200705144545p:plain

良いですね。

Reguler は、RictyDiminished と、おんなじ感じですし、Light はそれを細くした物のようになりました。ExtraLightLight は薄すぎですねぇ。

Discode版に関してですが、RictyDiminished の Discode版に対して以下の文字を除外しています。視認性より自然な風にしてみました。( 0 と r は 、点付きの 0 になってしまう対策です。なんでかな?)

<>:*+-0r7DZz"`

よし今後はこれを使っていくぞぉ。(* が、6本腕だったら完璧なのになぁ....)

フォントの話、Source Han Code JP と Ricty Diminished

最近本当に目が悪くなってきたため、モニターの小さな字を見るのがちょっと辛くなってきました。

その都度、エディタやターミナルのフォントを大きくしようかなと思い、フォント設定を変えてみたりしてたのですが、どーもしっくりこなくてすぐに、FixedSys に戻してしまうということを繰り返していました。

ちなみに、エディタは『秀丸エディタ』、ターミナルは『TeraTerm』です。

ですが、いよいよ文字が読みづらくなってきたため、やっぱり大きい文字にしようかなと思い立ち、グーグル先生に良いフォントが無いか聞いてみました。

そーすると、『xxxx年度版 コーディングフォント n 選』みたいなページがいくつも出てきまして、まぁそれらをみながら色々フォントをダウンロードして試してみました。

で、最初に選んだのが、『Source Han Code JP(源の角ゴシック)』です。

Source Han Code JP(源の角ゴシック)

ダウンロードしたフォントファイルに太さ別に7段階あり、ExtraLight, Light, Normal , Reguler, Middum, Bold, Heavy から選べます。このうち私 Light を選択しました。

これには理由があります。

過去に『どーもしっくりこなくて』戻した理由ですが、いずれも太すぎるためです。TTフォントって正直太すぎなのです。大きくすればするほどその太さが協調されてしまうわけです。大きくしたいだけで太くしたいわけでは無かったのです。 あまり太いと大げさかもしれませんが、ちょっとまぶしいんです。 乱視の為でしょうか...

ですから、このフォントの ExtraLight, Light です。大きくなっても太くならない。

よいでしょ。

でもダメでした。

しばらく使ってコーディングしていたのですが、なんか変です。

そう『秀丸エディタ』で文字のズレが発生し、TABルーラーと合ってないんです。

A<tab>B<tab>C<tab>D

A<sp3>B<sp3>C<sp3>D

とが ズレるのです。

これは痛い。特に保存時に TAB->SP 変換をしているため、保存してもう一度あけると、文字の位置が思ってたのと違ってたり、えぇぇぇ。なんで?となるわけです。

またズレ方も、フォントサイズが12ptだと SP幅が狭く、14ptだと微妙に合わず、16pt以上だと、SPが広くなり、ちょっとメンドクサイずれ方をするのです。

これはちょっとなと思い『秀丸エディタ』作者様の方へ相談してみたところ、 色々アドバイス頂いたり、対策を検討していただけるようなお返事をいただきました。(サイトー企画の斉藤秀夫様。ありがとうございます。)

しかーし。悪いのは『秀丸エディタ』ではない!このフォントがわるいのではないのか?っと思ってしまったら、もーなんか使いたくなくなってしまいました。

これが昨日までの話

ここからが半日苦労した話

Ricty Diminished

第二候補の Ricty Diminished です。

Ricty DiminishedはInconsolataと日本語フォントであるCircle M+ 1mを組み合わせたフォントです。』とあります。

ですがこのフォント、当然先ほど説明した通り、太いんです。

どーしよーかねーと思ってたところ、このフォントは同じ作者の Ricty がベースとなっていることが分かりました。

Ricty

rictyfonts.github.io

こちらのサイトをよく読むと、生成方法 というセクションに、 ricty_generator.sh というスクリプトで Inconsolata と M+ と IPA の合成フォント から 作る とあります。

えっ、自分で作れるの?

実は、最初にぐぐってるときに Inconsolata もちょっと調べてて、Inconsolata にも、太さ違いがあるのは分かってたのです。

fonts.google.com

ってことは、もしかして細い Inconsolata を使えばいいんじゃないか?

なんてことを思い至りました。

マイRicty

Ricty を動かしてみました

これが半日苦労した話の本題です。最初は1時間くらいでできるのだろーと思っていたのですよ。

例によって、うちの鯖である CentOS8 で、Ricty の生成方法にあるやり方を試してみました。

fontforge が入っていなかったので、インストールして実行します。

# sh ricty_generator.sh auto
Ricty Generator 4.1.1

Copyright (c) 2011-2017 Yasunori Yusa
All rights reserved.

This script is to generate Ricty font from Inconsolata and Migu 1M.
The generated fonts are licensed by both SIL Open Font License (OFL)
Version 1.1 and IPA Font License Agreement v1.0.
Due to OFL 1.1 Section 5, it is PROHIBITED to distribute the generated fonts.

Generate modified Inconsolata
Open ./Inconsolata-Regular.ttf
Remove ambiguous glyphs
Clear instructions
Save Modified-Inconsolata-Regular.sfd
Open ./Inconsolata-Bold.ttf
Remove ambiguous glyphs
Clear instructions
Save Modified-Inconsolata-Bold.sfd
Generate modified Migu 1M
Open ./migu-1m-regular.ttf
Scale down all glyphs (it may take a few minutes)
Clear instructions
Save Modified-migu-1m-regular.sfd
Open ./migu-1m-bold.ttf
Scale down all glyphs (it may take a few minutes)
Clear instructions
Save Modified-migu-1m-bold.sfd
Generate Ricty
ricty_generator.sh: 1100 行: 376309 中止                  (コアダンプ) $fontforge_command -script ${tmpdir}/${ricty_generator} 2> $redirection_stderr
Remove temporary files
Abnormally terminated

えーーーー!!!コアダンプって、シェルスクリプトで....

いろいろ調べてみますと、ricty_generator.sh で、fontforge に食べさせるスクリプトを作っているのですが、どーも fontforge 特定のコマンドで落ちる みたいなのです。で、なんか SetFontNames ってコマンドがいかんらしいことに気が付き

# diff -u  ricty_generator.sh.orig ricty_generator.sh
--- ricty_generator.sh.orig     2020-07-04 17:36:54.642050953 +0900
+++ ricty_generator.sh  2020-07-04 18:11:08.462849488 +0900
@@ -606,19 +606,19 @@
     Reencode("unicode")

     # Set configuration
-    if (fontfamilysuffix != "")
-        SetFontNames(fontfamily + fontfamilysuffix + "-" + fontstyle_list[i], \\
-                     fontfamily + " " + fontfamilysuffix, \\
-                     fontfamily + " " + fontfamilysuffix + " " + fontstyle_list[i], \\
-                     fontstyle_list[i], \\
-                     copyright, version)
-    else
-        SetFontNames(fontfamily + "-" + fontstyle_list[i], \\
-                     fontfamily, \\
-                     fontfamily + " " + fontstyle_list[i], \\
-                     fontstyle_list[i], \\
-                     copyright, version)
-    endif
+#    if (fontfamilysuffix != "")
+#        SetFontNames(fontfamily + fontfamilysuffix + "-" + fontstyle_list[i], \\
+#                     fontfamily + " " + fontfamilysuffix, \\
+#                     fontfamily + " " + fontfamilysuffix + " " + fontstyle_list[i], \\
+#                     fontstyle_list[i], \\
+#                     copyright, version)
+#    else
+#        SetFontNames(fontfamily + "-" + fontstyle_list[i], \\
+#                     fontfamily, \\
+#                     fontfamily + " " + fontstyle_list[i], \\
+#                     fontstyle_list[i], \\
+#                     copyright, version)
+#    endif
     SetTTFName(0x409, 2, fontstyle_list[i])
     SetTTFName(0x409, 3, "FontForge 2.0 : " + \$fullname + " : " + Strftime("%d-%m-%Y", 0))
     ScaleToEm(860, 140)
@@ -864,10 +864,10 @@
 # Open file and set configuration
 Open(filename)
 Reencode("unicode")
-SetFontNames(inputfamily + familysuffix + "-" + inputstyle, \
-             \$familyname + " " + familysuffix, \
-             \$familyname + " " + familysuffix + " " + inputstyle, \
-             inputstyle)
+# SetFontNames(inputfamily + familysuffix + "-" + inputstyle, \
+#             \$familyname + " " + familysuffix, \
+#             \$familyname + " " + familysuffix + " " + inputstyle, \
+#             inputstyle)
 SetTTFName(0x409, 3, "FontForge 2.0 : " + \$fullname + " : " + Strftime("%d-%m-%Y", 0))

 # " -> magnified "

こんなパッチをあててみたところ、途中まで動いて ttf ファイルができるようになりました。

でも、このパッチをあてると作者の copyright を故意に消すようなことになってしまいます。せっかくステキなスクリプトを作ってくれてるのに悪いですよねぇ....

ricty_generator.sh をググってみる

コアダンプで落ちる件を検索してみたのですが、なかなか見つかりませんでした。 というより、他の皆さんはちゃんとできてる んです。

こちらの方のブログが一番参考になりました。しかもつい数か月前の話ではないですか!

anime-sunpyo.jp

ふむふむ、Windows, Docker, ubuntu か...

この手の自分でビルドする系では、たいてい ubuntu ですよね。RedHat / CentOS 系って、手作業ビルドにむいてないですもんね...

でも Docker っての使えば、私の CentOS8 上で ubuntu 動くよね。

CentOS8 に Docker 入れてみたが挫折

で、早速 Docker を入れてみました。 これもまた、他者さんのまとめ記事をみながら、CentOS8 に Docker を導入。 ubuntu の Image を導入して、まったくDocker無知なのに、えいっと起動。

ここまではすんなりいったんです。 yum update でこけました。

ここから沼ってきました。以下の話はかなり端折ってます。

またまた色々やってみたのですが、どーやらDNS解決ができなくてホスト名が引けないよーです。 しかも Docker の ubuntuイメージには、本当に最小コマンドしか入ってなくって、ping すら入っていない。なにを試すにもコマンドがはいっていない....

しかたないので、centos8イメージをダウンロードしてきました。こちらは ping が入っていました。

で、ping IPアドレス だとちゃんと ping が通るのに、ping ホスト名 だとダメです。 /etc/resolve.conf を修正したり、ホストの firewall 触ったりしてみたのですが、すぐには解決しなさそうです。

うーん。そもそも Docker と格闘するって話ではなかったのですが、どんどん遠回りになってきました。

しかも ubuntucentos も、中身なーんにもはいってなくて、apt-get も yum も動かないんじゃ、なーんもできない。イライラマックスです。

ここまでで晩御飯の時間になり、頭が沸騰してしまいましたので、いったん休憩しました。

Windows10 WSL の ubuntu で試す。

Docker とは、どっかでまた勝負します。(うまいこと言った!)

Docker 自体は本題ではないので、とりあえずなにがしか ubuntu を最短時間で動かしたい。でもVMとかでのインストールメンドクサイ。

っとちょっとググっていると、Windows10 WSL の ubuntu が簡単そーだと知りました。

早速やってみたところ、確かに短時間で ubuntu が起動しました。ダウンロード時間はちょっとありましたけど、設定とか何にもしなくてログイン状態まで行ったのですから驚きです。

またこの ubuntu ですが、/mnt 配下に、ホストの windowsc:d: がマウント済みです。ubuntu 側から簡単にホストの windows ディレクトリが操作できます。こりゃいいや。

で、先の ricty_generator.sh を動かしてみると、あっさり完動! やったぜ

マイRictyの実際

先ほど紹介しました方のページにあるとおり、

  • ricty_generator.sh で Ricty フォントを作る
  • fontforge の結果では、フォント幅がおかしいので調整する

というステップが必要となります。

また私としては、Inconsolata-ExtraLight.ttf または、Inconsolata-Light.ttf と、migmix-1m-regular, migmix-1m-bold の組み合わせが使ってみたかったので、以下のような感じで実行してみました。

sh ./ricty_generator.sh -d "07DZz\"\`" -n -zuntan-el_ Inconsolata-{ExtraLight,Regular}.ttf migmix-1m-{regular,bold}.ttf
sh ./ricty_generator.sh -d "07DZz\"\`" -n -zuntan-l_  Inconsolata-{Light,Regular}.ttf      migmix-1m-{regular,bold}.ttf
sh ./ricty_generator.sh -d "07DZz\"\`" -n -zuntan-r_  Inconsolata-{Regular,Bold}.ttf       migmix-1m-{regular,bold}.ttf

for P in Ricty*.ttf; do
  ttx -t OS/2 "$P"
  sed -i.bak -e 's,xAvgCharWidth value="934",xAvgCharWidth value="505",' "${P%%.ttf}.ttx"
  mv "$P" "${P%%.ttf}.org.ttf"
  ttx -m "${P%%.ttf}.org.ttf" "${P%%.ttf}.ttx"
done

ちょっとテコ入れしたところは、07DZz\"\` -n -zuntan-XX_ value="934" value="505" です。

とくに、value="934" は、使ったフォントが違ったため、参考にした先の値とは違います。また、value="505" も Inconsolata のバージョンが違うためか、参考にした先の値とは違っています。それらを合わせるためには以下のコマンドを事前に実行しました。

for P in Inconsolata-*.ttf migmix-1m-*.ttf; do
 ttx -t OS/2 "$P"
done
grep xAvgCharWidth *ttx

これで目的のフォントが完成しました。

やったー。ここまででもう21時です。

fontforge のバージョン確認

一応 CentOS8 と ubuntufontforge を確認してみます。

  • CentOS8
# cat /etc/redhat-release
CentOS Linux release 8.2.2004 (Core)

# fontforge --version
Copyright (c) 2000-2014 by George Williams. See AUTHORS for Contributors.
 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
 with many parts BSD <http://fontforge.org/license.html>. Please read LICENSE.
 Based on sources from 18:43 UTC 24-Apr-2020-ML-D.
 Based on source from git with hash:
no xdefs_filename!
TESTING: getPixmapDir:/usr/share/fontforge/pixmaps
TESTING: getShareDir:/usr/share/fontforge
TESTING: GResourceProgramDir:/usr/bin
trying default theme:/usr/share/fontforge/pixmaps/resources
fontforge 18:43 UTC 24-Apr-2020
libfontforge 20200424
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal

$ fontforge --version
Copyright (c) 2000-2020. See AUTHORS for Contributors.
 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
 with many parts BSD <http://fontforge.org/license.html>. Please read LICENSE.
 Version: 20190801
 Based on sources from 03:10 UTC  6-Mar-2020-ML-D-GDK3.
fontforge 20190801
build date: 03:10 UTC  6-Mar-2020

ふむふむ。ubuntu の方がちょっと古いもののように見受けられます。fontforge さーん。バグ入れちゃったみたいですよぉ~

訂正 : 確認方法がまずかったようです。

  • CentOS8
$ dnf info fontforge
メタデータの期限切れの最終確認: 0:03:56 時間前の 2020年07月05日 16時51分54秒 に実施しました。
インストール済みパッケージ
名前         : fontforge
バージョン   : 20170731
リリース     : 14.el8
Arch         : x86_64
サイズ       : 18 M
ソース       : fontforge-20170731-14.el8.src.rpm
リポジトリー : @System
repo から    : PowerTools
概要         : Outline and bitmap font editor
URL          : http://fontforge.github.io/
ライセンス   : GPLv3+
説明         : FontForge (former PfaEdit) is a font editor for outline and bitmap
             : fonts. It supports a range of font formats, including PostScript
             : (ASCII and binary Type 1, some Type 3 and Type 0), TrueType, OpenType
             : (Type2) and CID-keyed fonts.
$ apt-cache show fontforge
Package: fontforge
Architecture: amd64
Version: 1:20190801~dfsg-4
Multi-Arch: foreign
Priority: optional
Section: universe/x11
Origin: Ubuntu
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: Debian Fonts Task Force <debian-fonts@lists.debian.org>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 129
Depends: fontforge-common (= 1:20190801~dfsg-4), libfontforge3 (= 1:20190801~dfsg-4), libgdraw6 (= 1:20190801~dfsg-4), libc6 (>= 2.2.5)
Suggests: fontforge-doc, fontforge-extras, potrace, python3-fontforge
Conflicts: fontforge-nox
Filename: pool/universe/f/fontforge/fontforge_20190801~dfsg-4_amd64.deb
Size: 25896
MD5sum: 06f29ed81385986dfaa2eca51d489a82
SHA1: ddb7360b5efa2e355670b6051c9669fc4f1f341c
SHA256: e22a1f561183cf26372ba0ae01bed5c4615b77ad9ca361300837758d8cc448d8
Homepage: https://fontforge.github.io/en-US/
Description-en: font editor
 FontForge is a font editor.
 Use it to create, edit and convert fonts
 in OpenType, TrueType, UFO, CID-keyed, Multiple Master,
 and many other formats.
 .
 This package also provides these programs and utilities:
  fontimage - produce a font thumbnail image;
  fontlint  - checks the font for certain common errors;
  sfddiff   - compare two font files.
Description-md5: 4ebffb1f6ab9a1d49bd81ce04ad8a0a7
Task: ubuntustudio-publishing

CentOS8 の方は 20170731 とあり、ubuntuの方は 20190801 とあります。CentOS8 の方は、かなり古いみたいです。

マイRictyの見栄え

最後に、どんな見栄えになったかです。

  • Inconsolata-Regular (400) + migmix-1m-regular

f:id:zuntansan:20200705005131p:plain

  • Inconsolata-Light (300) + migmix-1m-regular

f:id:zuntansan:20200705005139p:plain

  • Inconsolata-ExtraLight (200) + migmix-1m-regular

f:id:zuntansan:20200705005141p:plain

私としましては、Inconsolata-Light がちょうどいい感じですね。比べると Inconsolata-Regular でもいい気がするのですが、ちょっと強いかなぁ。Inconsolata-ExtraLight はちょっと薄すぎですね。ははは。

で、『秀丸エディタ』では Inconsolata-Light、『TeraTerm』では Inconsolata-Regular にすることにしました。

ああ、半日以上かかってやっと満足した結果が出せました。よーし。ビール飲むぞ!

追記

Inconsolata と Circle M+ 2m の組み合わせに変更しました。

MPDとRustとRaspberryPiで遊んでみる8

さて、MPDのフロントエンドを作ろうという目標を立てて、Volumio や Moode には及ばずとも、ソレっぽいのを作ろうと鋭意がんばっています。

ちょっとだけソレっぽいものが出来つつあるので、リポジトリを公開します。

github.com

プロダクトタイトルは、『飛騨茉莉』です。『陽だまり』と、私の田舎とのモジリです。

https://github.com/zuntan/hidamari/raw/master/hidamari.png

前回実装した FFT での スペクトル解析データを使って、曲が再生している間、ちょっとしたビジュアルアニメーションをみることができるよーになってます。

PCブラウザからも、携帯ブラウザからも、同じように操作できますし、ビジュアルアニメーションも同じように動きます(携帯だとちょっと重いかも...)。アニメ速度は予想していたより高速で軽快です。Websocket を使ってサーバー側のタイミングでデータ送るようにしオーバーヘッドが少ないようにしようと狙ったのが功を奏したのかもしれません。

https://github.com/zuntan/hidamari/raw/master/screenshot/008.png

https://github.com/zuntan/hidamari/raw/master/screenshot/010.png

youtu.be

リポジトリに方には、スクリーンショットが置いてあります。まぁ、デザインのプロではないため、画面はやや地味ですが、HTMLファイル1つとJavaScript1本だけで作られていて、 サーバー側にはすべて、Ajax REST と Websocket でやり取りしてますので、見た目はイチからフルカスタマイズ可能です。

サーバー側としては、あと Bluetooth の接続、シャットダウンなどの IF を 入れることと、Raspberry Pi での動作確認などです。CentOS 8 では CPUを 10~15% 程つかいます。ロードアベレージは、0.1 ~ 0.2 です。これが RPi 3 でどのくらいになるのか、ちょっと心配です。

UI 側は、動的設定画面を追加することと、いまのところデフォルトテーマ1つだけ、それも Bootstrap 臭がプンプンのデザインですので、もう一つ違ったテーマを作ってみたいと思います。

スペクトルデータのビジュアライズの部分もできれば、プラグイン化したいかな。

ちょっと残念なのが、曲のアルバムビジュアルを出そうと思ってたのですが、MPD が未だサポートしていませんでした。マニュアルにはソレっぽい記述があるのですが、次のバージョンで実装するそーで現状では独自に実装する以外ちょっと無理っぽいです。Volumio や Moode はそれが出来ているので、むつかしいことしてそーですね。

MDPでアルバムビジュアルが取れるようになれば、速攻組み入れたい機能ですね。

RPi 3 で遊ぶために、かなり遠回りしてますが、そろそろ RPi 3 に戻ってこれそー。です。

MPDとRustとRaspberryPiで遊んでみる7

前回からちょっと間が空きました。うーん Rust とちょっとずつ仲良くなっているよーな気がします。 最終的には、Rust で MPDフロントエンドを作ろうと思っており、鋭意進めております。

ですが、ちょっと脇道にそれて実験をしてみました。

MPD の fifo 出力で遊んでみる。

MPD が再生しているときに、その PCM データをネームドパイプに出力できるよーです。

ってことは、それを使ってスペアナが作れるかも!

っと思い立ったら、モー止まらなくなりました。

で、ひたすらグーグル先生にお尋ね回りまして、いろいろ拾いまくった挙句なんとか形になりました。

github.com

やったぜ!

パラパラしたりパタパタしたり、右チャンネルが消えてしまったりしてますが、 レートの低い GIF にしたためです。実際もちょっとマシにアニメします。

いやぁ、大変でした。

何が大変って、FFTなぞさっぱり分からない人間がどーやったらかっちょいい感じにリアルタイムでピコピコ動く物を作るのかってのが、いやはや難題でした。

FFT高速フーリエ変換)あるいは、DFT(離散フーリエ変換)という物があるのは知っていたのですが、どーやって使うのかが、さっぱりわからなかったのです。

WEVEデータ -> FFT -> スペクトル

これは理解できます。ただ、この「スペクトル」となったデータ列を、どーやったら見えるものにできるのか?という点に関して、なかなかバシッと答えを書いている記事が見つけられなかったのです。

FFT の理屈を説明する記事や、スペクトルをグラフ化している記事は多々あるのです。しかし、グラフ化していても、それの数値の単位やスケールなどバラバラで、値の大小は分かるのですが、それがバシッと何なのか?というてんでは、皆さん興味が無いよーで、単位もバラバラ、どういう範囲で値がとれるのかも不明。その値の加工方法もさっぱりで、なかなかそこから先どーすればいいかがわかりませんでした。

私のよーな無学のエセ錬金術師にとっては、鶏が卵を産むように、卵(と鶏)にしか興味がなく、その間プロセスは正直そこまで大事ではないです。いわゆるこんな感じ。

鶏         -> どーでもいい -> 卵
WEVEデータ ->       FFT      -> スペクトル

もっとひどく言えば、桶屋が儲かった話では、桶屋にしか興味がないわけで、風がどーなったかはまぁ...

あとは、卵の料理の仕方なのですが、それが分からん!

イメージとしては『周波数ごとに、0 から 100 までの幅を持つ値が取りたい』のです。

結局それを調べるために、何日も検索し続けたりしてたんですが、なんかピカっと光る記事は見つけられませんでした。挙句には、何とかヒントをと Interface (インターフェース) 2016年 6月号 まで買って読んだのですが、うーん。でした。

しかし、逆に言えば、たいした決まりは無いのかもしれない。と思い立った瞬間、『好きなように加工してしまえ』と半ばやけくそでテキトーな倍率や補正関数をかけてみたら、なんかちょっとソレっぽい動きをする数値がとれるよーになり、いけるかもーとなりました。

で、そこまで行くと可視化したいわけですが、ここでも詰まります。

パッと可視化したいわけですが、相手が音楽だけにリアルタイムで変化する可視化となります。 ふつうは GUI ってことになりますが、そーすると GUIライブラリだとかのお勉強で、また遠回りとなります。 そーでなくても Linux, Windows とか GTK, Qt, etc... と、最初の壁がちょっと高いわけです。しかもまだRust不慣れだし。

何とかならんもんか...

GUIツールキットは避けたいなと思い、画像を細々と出して、ffmpeg で動画にしてはどーかと思いました。 しかしこれも、なかなかメンドクサイ。PNGを作るとしても、描画処理かかなければならないですからね。なにがしかのライブラリの世話になることになり、そこそこ手間です。Rust不慣れだし。

SVGを出力して、画像にするのは外部プログラム使うという手を思いつきました。

で、やってみたのですが、今度は音楽と同期させるのがむつかしいことに気が付きました。 そこそこ出音と合う動画をつくろうとしたら、出音の経過時間に対してピッタリあった画像を生成しなければいけないのですが、相手が単なる waveファイルなら、まだ計算できるものの、mpd の fifo は、生の PCMデータがひたすら流れ続けているだけでどこが最初かすらよくわからな物ですので、ずれたらどれだけズレたのかすら分かんないわけです。(実際プログラムが完成したら、そーでもなかったわけですが...)

自分のプログラムのバグでずれているのか、そもそもズレを認識するにはどーすればいいか、などなどよけーややこしそーだなぁ。とこの案は却下としました。

やっぱりリアルタイムでアニメしないとダメだ。第一そのほーが見てて楽しいじゃないか!音楽に合わせてピコピコうごかしたいじゃないか!

GUIがだめなら、CUIか。ncurses か。rust で ncurses も、そこそこメンドクサイ。だって ncurses つかったことないし...

っとそんなところに、こちらの記事

meganehouser.github.io

この記事と、この方のプログラムが、正に私にとっての福音でした。 そーか、ANSIエスケープシーケンスで、コンソールに出力しまくればそこそこアニメできるんだ!

この方のソースコードを拝借( git clone ) して動かしてみたら、結構動くじゃない~ アニメ速度を決める定数をかなり早くしても、そこそこ動くんです。15fpsくらいは行けてるみたいでした。 これは十分です。コードもチョー短いし。なんたって、単なるながーい文字列つくって、標準出力にだすだけですから、知識は不要です。

いけるぜ!ビバ・コンソールアプリ!

で、出力周りをととのえて、えいや!と動かしたのですが、全然動かんかったり、動きが右と左でちがってたりして、( u8バッファから i16バッファへの積み替えの際に、2バイトずつ読むとこを1バイトしかずらしてなかった) そもそも最初にもどって、スペクトルのデータの数値の単位がよーわからんので、バーが全部てっぺんに当たってどーすればいいんじゃーってなったり...

でもなんか色々やっているうちに、だんだんソレっぽい動きをしてきて、何とか見れるよーになってきました。

で、ソレっぽいのは分かったのですが、ソレがあっているのはどーすれば検証できるのか?答えがないのに...波ってむっつかしー。

うーん。音で調べるしかないか。

で、普通の音楽データを使うと、わけわからなので、サイン波を使ったわけです。

1khz のサイン波の wave ファイルを MPD に再生させながら、作ったプログラムをみてみたら、おおーそれっぽい!

で調子にのって、

  • いろいろな周波数のサイン波の wave ファイル (周波数帯ごとの出力確認)
  • ステレオ(2ch) だけど、左だけ、右だけ無音の wave ファイル (左右の出力確認)
  • 一定間隔で 無音になる wave ファイル (出てる音と描画のタイミングの確認)
  • ふつうのノイズの wave ファイル (各周波数帯の出力が同じレベルかの確認)
  • ピンクノイズの wave ファイル (聴感的に各周波数帯の出力が良い感じなのかの確認)

これらを作ったうえで、MPD に再生させながら色々調整していきました。もー理論とかじゃなく、見た目重視で色々パラメーター変えながら地道に。最終的には上3つはデバックに、下二つはレベルメーターの動きの調整に役に立ちました。

waveファイルの作成はこれが最高でした。

soundengine.jp

これの WaveGenerator が簡単にサイン波 waveファイルが作れましたし、音自体の加工もこれで簡単にできました。

とくに、「一定間隔で 無音になる wave 」が意外と役に立ちました。これがあったため、MPDの出力と同期させるように調整するのが、はかどりました。

ただ、まだ最後の山があって、MPDさん。waveファイルだと出音とピッタリ同期したPCMデータを出すのに、mp3 だと PCMデータと出音が 0.5秒くらいズレるんです。そう。上の「一定間隔で 無音になる wave 」を ffmpegでmp3 に変換して食べさせると思いっきりズレるんです。

で、PCMデータが遅れるんなら、デコードとかがあってしゃーないのかなとか思うのですが、音が遅れて出てくるんです。えっ?

だって、既にデコードしたデータがあって、fifoに出力もしているのに、そのままALSAにぶち込むだけで音出るよね?そのあと0.5秒も遅らせてから出すのってなんで? waveは遅れないのになんで?わざわざmp3だけディレイしてんの?

環境・設定の問題なのかと色々考えたり確認したのですが、いやー...

少し遅れるんならまだあれですが、0.5秒って相当です。手拍子がみんなと反対になるくらい相当です。行進がみんなと反対になるくらい相当です。(いますけどね。そういう方...私もリズム感が特別いいわけでは無いのであれですがね。)

まぁ、しゃーないので、こっち側で 0.5秒ほど遅らせてアニメするようにしました。ただ、waveだと遅れないってことは、ライブラリに mp3とwaveが混在してたら、どっちかでは必ずずれるんですよねぇ...。まぁ mp3だけにしておけば、いいっちゃいいんですがね...。

色々ありましたが、出来たコードみたら「こんなもんか」なのですが、作るって大変だなとしみじみ思います。

でもうふふ。出来たものを見てるのは楽しい。昔の(また昔話)カーステレオの派手な奴みたいに、好きな音楽に合わせてピコピコ動くのは、見てて飽きないですねぇ。

よし、これに合わせて、LEDをチカチカさせれば....などという欲望がわいてきました。(ってか最初っからそれが目的で...)

んま、Rustもわりと色々を使ってみて、武器として使えるライブラリも着々と増えてきたので当初よりコーディングスピードは上がってきましたね。だんだん慣れていければいいなぁ。

MPDとRustとRaspberryPiで遊んでみる6

前回で、とりあえず Rust で1本つくってみたわけですが、CentOS8 上で作ったので当然 CentOS8 上でしかうごきません。 将来的には Raspberry Pi 上で動くものを作りたいわけです。 そーしたばあい、『Raspberry Pi に Rust を入れてコンパイル』することになるかと思うのですが、 Rustはコンパイルが速いわけでも無さそーですし、RPi も早いわけではない。ディスクそこまで早くない。

ってことで、こんな時こそ『クロスコンパイル』です。

で、いろいろ Google 先生にお伺いたててみたのですが、母艦が Ubunt の記事しか見当たらない!

うむ~、うちの母艦は、CentOS8だしなぁ... どぉ~しようかなぁ...

を!あった。

qiita.com

って、自作自演です。頑張ってみました。

で、さっそく前回作った mpdsh を RPi 用にコンパイルします。

github.com

.cargo/config をちょっと修正しまして...

[target.armv7-unknown-linux-gnueabihf]
linker = "/home/zuntan/cross_rp_3/bin/arm-linux-gnueabihf-gcc"

ビルド!

cargo build --target armv7-unknown-linux-gnueabihf

あっさりできました。

file target/armv7-unknown-linux-gnueabihf/debug/mpdsh
target/armv7-unknown-linux-gnueabihf/debug/mpdsh: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, with debug_info, not stripped

ファイルがでかい!けどまぁいいか

$ ls -lh mpdsh
-rwxr-xr-x 1 zuntan zuntan 22M Jun 17 18:39 mpdsh

で、RPi にもっていって実行!

$ ./mpdsh
Connecting... localhost:6600
connected OK MPD 0.21.11

mpdsh:/> ls
directory   : RADIO
mpdsh:/> cd RADIO
mpdsh:/RADIO> ls
file        : NPO Radio 2.pls
file        : France Inter Paris (FIP).pls
file        : Audiophile Baroque.pls
file        : WRTI Philadelphia 90.1 - Classical.pls
file        : BBC Radio 3.pls
:
:

ちゃんと動きました。

Rust による『クロスコンパイル』の手ごたえを見るための実験でしたが、良いですね。大きな問題は無さそーです。

次はもーちょっと本格的なものをビルドしてみます。

actix-web を ビルド!

volumio や moore のような MDPのフロントエンドを作ろうとしたら、webサービス形式となるわけです。

actix-web は いわゆる web application framework ってやつで、これがコンパイルできて RPi で動けば、よさそうな感じとなります。

github.com

Example にある内容をもとに、IPアドレスとポート番号だけ変更して普通にコンパイルしてみたところ、サクッと動きます。 では、次に arm版のビルドをします。

$ cargo build --target armv7-unknown-linux-gnueabihf
:
:
   Compiling brotli-sys v0.3.2
error: failed to run custom build command for `brotli-sys v0.3.2`

Caused by:
  process didn't exit successfully: `/home/zuntan/rust_test/actix-web/target/debug/build/brotli-sys-df9db23f522cf66e/build-script-build` (exit code: 1)
--- stdout
cargo:include=/home/zuntan/.cargo/registry/src/github.com-1ecc6299db9ec823/brotli-sys-0.3.2/brotli/include
TARGET = Some("armv7-unknown-linux-gnueabihf")
OPT_LEVEL = Some("0")
HOST = Some("x86_64-unknown-linux-gnu")
CC_armv7-unknown-linux-gnueabihf = None
CC_armv7_unknown_linux_gnueabihf = None
TARGET_CC = None
CC = None
CROSS_COMPILE = None
CFLAGS_armv7-unknown-linux-gnueabihf = None
CFLAGS_armv7_unknown_linux_gnueabihf = None
TARGET_CFLAGS = None
CFLAGS = None
CRATE_CC_NO_DEFAULTS = None
DEBUG = Some("true")
CARGO_CFG_TARGET_FEATURE = None
running: "arm-linux-gnueabihf-gcc" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-march=armv7-a" "-I" "brotli/include" "-o" "/home/zuntan/rust_test/actix-web/target/armv7-unknown-linux-gnueabihf/debug/build/brotli-sys-c4c720afbb1107ee/out/brotli/common/dictionary.o" "-c" "brotli/common/dictionary.c"

--- stderr
fatal: not a git repository (or any of the parent directories): .git


error occurred: Failed to find tool. Is `arm-linux-gnueabihf-gcc` installed?



warning: build failed, waiting for other jobs to finish...
error: build failed

あらら。

C のコードをコンパイルしようとして失敗しているよーですね。

error occurred: Failed to find tool. Is `arm-linux-gnueabihf-gcc` installed?

ってことは arm-linux-gnueabihf-gcc が参照できればいけるのかな? 自作の arm-linux-gnueabihf-gcc があるディレクトリにパスを通してもう一度実行してみたところ、見事にビルド完了。やったぜ!

$ export PATH=/home/zuntan/cross_rp_3/bin:$PATH
$ echo $PATH
/home/zuntan/cross_rp_3/bin:/home/zuntan/.cargo/bin:/home/zuntan/.local/bin:/home/zuntan/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/zuntan/.dotnet/tools
$ cargo build --target armv7-unknown-linux-gnueabihf
:
:
   Compiling serde_urlencoded v0.6.1
   Compiling actix-router v0.2.4
   Compiling actix-http v1.0.1
   Compiling awc v1.0.1
   Compiling actix-web v2.0.0
   Compiling actix-web v0.1.0 (/home/zuntan/rust_test/actix-web)
    Finished dev [unoptimized + debuginfo] target(s) in 39.66s
$ file target/armv7-unknown-linux-gnueabihf/debug/actix-web
target/armv7-unknown-linux-gnueabihf/debug/actix-web: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, with debug_info, not stripped

で、できた target/armv7-unknown-linux-gnueabihf/debug/actix-web を RPi にもっていって、実行すると見事に動きました。

ちなみにファイルサイズは、78M

ls -lh target/armv7-unknown-linux-gnueabihf/debug/actix-web
-rwxrwxr-x 2 zuntan zuntan 78M  6月 17 20:51 target/armv7-unknown-linux-gnueabihf/debug/actix-web

リリースビルドもしてみました

$ cargo build --release --target armv7-unknown-linux-gnueabihf
   Compiling libc v0.2.71
   Compiling proc-macro2 v1.0.18
   Compiling unicode-xid v0.
:
:
   Compiling actix-http v1.0.1
   Compiling awc v1.0.1
   Compiling actix-web v2.0.0
   Compiling actix-web v0.1.0 (/home/zuntan/rust_test/actix-web)
    Finished release [optimized] target(s) in 1m 08s

170近くある外部モジュールのコンパイルを考えれば、1m 08s でコンパイルできるのはすごく早いのかもしれませんね。

$ file target/armv7-unknown-linux-gnueabihf/release/actix-web
target/armv7-unknown-linux-gnueabihf/release/actix-web: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, with debug_info, not stripped
$ ls -lh target/armv7-unknown-linux-gnueabihf/release/actix-web
-rwxrwxr-x 2 zuntan zuntan 6.2M  6月 17 21:06 target/armv7-unknown-linux-gnueabihf/release/actix-web

with debug_info, not stripped って書いてある割には、 6.2M です。C/C++が埋め込むよーな内容を Rustが埋め込んでいないからだと推測します。 試しにファイルをコピーして strip してみました。

$ cp target/armv7-unknown-linux-gnueabihf/release/actix-web{,-ns}
$ /home/zuntan/cross_rp_3/bin/arm-linux-gnueabihf-stri
arm-linux-gnueabihf-strings  arm-linux-gnueabihf-strip
$ file target/armv7-unknown-linux-gnueabihf/release/actix-web
target/armv7-unknown-linux-gnueabihf/release/actix-web: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, stripped
$ /home/zuntan/cross_rp_3/bin/arm-linux-gnueabihf-strip target/armv7-unknown-linux-gnueabihf/release/actix-web
$ ls -lh target/armv7-unknown-linux-gnueabihf/release/actix-web*
-rwxrwxr-x 2 zuntan zuntan 2.7M  6月 17 21:12 target/armv7-unknown-linux-gnueabihf/release/actix-web
-rwxrwxr-x 1 zuntan zuntan 6.2M  6月 17 21:11 target/armv7-unknown-linux-gnueabihf/release/actix-web-ns
-rw-rw-r-- 1 zuntan zuntan 136  6月 17 21:06 target/armv7-unknown-linux-gnueabihf/release/actix-web.d

2.7M まで小さくなりました。

actix-web を RPi にもっていって実行してみました。ちゃーんと動きました。

Rust すごい

Rust の クロスコンパイルを試してみました。

少なくとも CentOS8があれば、RPi でコンパイルしなくても作れるってことが分かりました。

Windows でのクロスコンパイルは、そこそこ記事が検索できたので、たぶんそっちも問題ないんだと思います。

すばらしいポータビリティーです。(一時はヒヤッとしましたが...)

ロマン

やっぱり『クロスコンパイル』はロマンがありますねぇ~

やべぇ、『 windowsで走る arm用 gcclinuxでビルド』したらどーなるのかと...思っちゃいました。なんかできーそーだけどね。 VSCode 使って Windows で開発するほーが楽そーだしなぁ... やべぇ、隣の山を登りだしそうだ...