Debian/UbuntuのMultiArch対応 〜/lib/x86_64-linux-gnuとか/lib64とか〜
gdbでlibcの中の関数までバックトレースしたかったり、valgrindでメモリリーク調査をしたかったりすると、libcのデバッグ版が必要になる。
PC Linuxなら、Debian系ならlibc6-debugをインストールしてやれば良いのだが、ARM上で組込み用のLinuxが動いているような環境では、パッケージでインストールされるファイルに相当するものを手で入れることになる。どのディレクトリにどんなファイルを入れれば良いのか把握していないといけないわけで、そこでMultiArch対応という仕組みの理解が求められる。
gdbやvalgrindはどうやってデバッグ版libcの場所を見つけるのか
libc6-debugをパッケージインストールすると、パッケージ内のファイルは/usr/lib/debug配下にコピーされる。
どうやら、gdbやvalgrindはデフォルトで/usr/lib/debugをデバッグ版ライブラリのサーチパスとして持っているらしい。
もちろんサーチパスの変更は可能で、gdbの場合は「set debug-file-directory」というコマンドでできる。valgrindの場合は、「--extra-debuginfo-path」オプションで設定できる。
https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html
http://valgrind.org/docs/manual/manual-core.html
/usr/lib/debugの下に、オリジナルのライブラリと同じディレクトリ構成でライブラリファイルを置いてく必要がある。
例えば、/lib/x86_64-linux-gnu/libc-2.15.soの場合、/usr/lib/debug/lib/x86_64-linux-gnu/libc-2.15.soという感じ。
/usr/lib/debugの直下に/usr/lib/debug/libc-2.15.soという形で置いておいても認識してくれないので注意。
MultiArch tuple
32bit互換の64bit CPUが出てから、同じシステム上で32bitアプリと64bitアプリの両方が動く環境が求められるようになった。
Linuxの場合、システムライブラリは/lib、/usr/libに配置される慣習なので、32bit版はこれまで通り/libに、64bit版は/lib64という形で配置されていた。
これはIntelの32bit、64bitを区別するぶんには機能するけるども、ABIの違いは表現できていないので将来ABIが変わった場合にはどうするんだとか、IA-64とかは64bitのライブラリだけど32bitじゃないから/libに配置されるわけでわかりづらいぞ、ARMとかMIPSとか別のCPUアーキテクチャでも32bitと64bitがあるけどどうするんだという、課題があって廃止になった。
で、代わりに使われるようになったのが/lib/
もともとはGNUのツールチェインなんかで使われてたtuple表現をそのまま使おうとしたらしいけども、ライブラリが対応するABIを表現するには曖昧だったり、不適切だったりする場合があって、一部はそのまま使って、一部は表現を変えているらしい。
tupleの一覧は下記にまとめられている。
https://wiki.debian.org/Multiarch/Tuples
その他の参考サイト。
https://wiki.ubuntu.com/MultiarchSpec
ローダとの関連
結局どのライブラリを使うかというのは、ローダが決めることなので、ABIごとにそれ用のローダがある。逆に言うとローダさえ決まっていれば使われるライブラリが決まる。どのローダを使うかは、コンパイル時に実行ファイルに埋め込まれる。glibcがサポートするABIごとのロードの一覧がここにまとめられている。
https://sourceware.org/glibc/wiki/ABIList
https://wiki.linaro.org/RikuVoipio/LdSoTable
Google Driveをバックアップメディアとして使う
Google Driveをローカルストレージとの同期なしで使う方法
Google Drive。ふつうにインストールすると、ローカルドライブの内容とクラウドの内容が同期される。
これはこれで便利だが、クラウドのストレージ容量と同量のローカルストレージが必要になる。
クラウド側のストレージは価格がどんどん下がって手が出しやすくなっているが、ローカルのストレージがSSDなノートPCでは、サイズの関係がクラウド>ローカルとなって、いまいち使いにくい。
このような環境では、ローカルとの同期はなしで、純粋に拡張HDDとしてクラウドストレージを使いたくなる。
調べてみたら幾つかやり方はあるようだ。
- Expandrive
http://ta21u.hateblo.jp/entry/2014/08/21/004729
- Transmit
http://augustdesign.info/130.html
これらはGoogle Driveを外付けHDDのようにマウントして使えるようになるもの。
マウント後は普通のディレクトリと同じようにファイルの追加削除ができるので便利。
実際、Expandriveの方は期間限定のフリー版があったので使ってみたが、気持ちよく使えた。
問題は、どちらも有償であるということ。5000円くらいする。機能のわりにちょっと高い気がする。
- gdrive
http://www.webupd8.org/2014/09/gdrive-simple-google-drive-cli-client.html
これはGoogle Drive上のファイル操作用のCUIコマンドを提供するツール。おそらくGDrive APIを使っている。
上記の二つのようにファイルシステムに統合されるわけではないので、使い方は制限される。例えば、Google Driveを特定のファイルのバックアップ先にするような用途であれば十分使えそう。
今回は3番目のgdriveツールを使って、写真のバックアップをGoogle Driveにしてみる。
Macへのgdriveのインストール
- ダウンロードとインストール
https://github.com/prasmussen/gdrive#downloads
からMac OS用(drive-darwin-amd64 v1.3.0)をダウンロード。
ダウンロードしたバイナリを適当なフォルダにコピーした後で実行権限をつけておく。
- 設定
最初にAPIを叩くための認証コードを取得する。
コマンドを始めて実行すると下記のような感じでURLが表示されるので、ブラウザに入力する。
で、発行されるトークンをEnter verification code: の所に入力すれば完了。
$ ./drive-darwin-amd64 Go to the following link in your browser: https://accounts.google.com/o/oauth2/auth?client_id=XXXXXXX Enter verification code:
使ってみたが、複数のファイルやディレクトリを再帰的にアップロードするには、一手間必要そう。
gdrive自体はコマンドラインツールなのでその標準出力を文字列処理して云々が必要。
スクリプトを書くことでできなくはないが、API的なものを使ってCなりJavaなりで書いた方が楽そう。
nin drive
nin driveの17,000曲をどうやって聴くか
http://www.ninlive.com/navbar/drive.html
Nine Inch Nailsのファンが録音したライブ音源が500GB分ダウンロードできる。
bittorrentでダウンロード完了。
ほとんどの音源がflacフォーマットなので、そのままではiPhoneで聴くのに不便。
flacからmp3に変換して、itunesにぶち込んで、itunes matchでストリーミング再生できるようにしてみる。
nin driveの曲数はざっくり17,000。
# find ./ -type f -print | sed -e 's/^.*\///' | grep '\.' | sed -e 's/^.*\.//' | sort | uniq -c | sort -nr 15467 flac 1662 txt 934 jpg 887 md5 846 mp3 143 m4a 82 FLAC 47 mp2 22 db 18 wma 10 DS_Store 3 ini 3 TXT 1 rtf 1 nfo
itunesの登録曲数は4499。
iTunes matchは最大25000曲までらしいので残りざっくり20,000。
活かしきれていないストレージ容量を一気に使う。
今後のために、今と同じくらいの曲数は登録できるように残しておきたいのでつかえるのは15,000にしておこうかな。
flacをalac(Apple Lossless Audio Format)に変換してiTunesに登録
とりあえず一番あたらしい2014の音源についてitunesへの登録をやってみる。
nin2014のディレクトリ数は59。
nin2014-02-25.iem-aud.xavelrecords.0.flac1644 →ALAC nin2014-02-25.v-75.tn.0.flac1644 nin2014-02-26.iem-aud.newtattoo.0.flac1644 →MP3 nin2014-02-26.v-75.tn.0.flac1644 nin2014-02-28.csb.smores.0.flac2448 nin2014-02-28.iem-aud.newtattoo.0.flac1644 nin2014-02-28.iem-aud.xavelrecords.0.flac1644 nin2014-03-06.okmii.mattg.0.flac1648 nin2014-03-07.okmii.mattg.0.flac1648 nin2014-03-08.okmii.mattg.0.flac1648 nin2014-03-11.gopro.vee.0.flac1648 nin2014-03-14.ecmds70p.kingbean.0.flac1644 nin2014-03-14.okmii.mattg.0.flac1648 nin2014-03-15.ca11.brotherruprecht.0.flac1644 nin2014-03-15.okmii.mattg.0.flac1648 nin2014-03-27.sbd.pro.0.mp3192 nin2014-04-01.sbd.eva0001.0.mp3246 nin2014-04-05.sbd.thebang-cynicmuse.0.acc62 nin2014-05-13.m10.dc.0.flac2496 nin2014-05-15.at933.stefler.0.flac1644 nin2014-05-18.at853.polewka.0.flac1644 nin2014-05-18.ck63.bobstammers.0.flac1644 nin2014-05-18.cmc25.bobstammers.0.flac1644 nin2014-05-20.ecm717.tm.0.flac2448 nin2014-05-23.iphone5s.solarez.0.flac1644 nin2014-05-24.at853-ca-14.polewka.0.flac1644 nin2014-05-25.at853-ca-14.polewka.0.flac1644 nin2014-05-25.cmc8.rbose1.0.flac1644 nin2014-05-25.icd-ux81.abjectmark.0.flac1644 nin2014-05-27.at933.stefler.0.flac1644 nin2014-05-27.at933.stefler.0.flac2448.wav nin2014-05-27.ccm41v.ianmacd.0.flac1644 nin2014-05-28.ecm717.tm.0.flac2448 nin2014-06-03.icd-ux512s.tatranky.0.flac1644 nin2014-06-04.at933.stefler.0.flac1644 nin2014-06-04.km140.alysha.0.flac1644 nin2014-06-04.m10.dc.0.flac2496 nin2014-06-04.mbho.sebi2704.0.flac1644 nin2014-06-09.atu853c.mrruin.0.flac1644 nin2014-07-19.mk4cmr-mk4cmr.rainingvodka-michelevr5.0.flac2448 nin2014-07-21.at831.tapeworm48.0.flac1644 nin2014-07-21.ca14.bt.0.flac2448 nin2014-07-22.at831.tapeworm.0.flac1644 nin2014-07-22.mk41.bt.0.flac2448 nin2014-07-24.ccm4.ryanj.0.flac2448 nin2014-07-24.mk41.darktrain.0.flac1644 nin2014-07-26.ccm4.ryanj.0.flac2448 nin2014-07-29.at853.opsopcopolis.0.flac1644 nin2014-07-29.m10.ericcagle666.0.flac1648 nin2014-07-30.mk4.nickyc.0.flac1644 nin2014-08-07.iem.univoc.0.flac2448 nin2014-08-10.cmc2.ligushka.0.flac1644 nin2014-08-16.ecm717.ryanj.0.flac2448 nin2014-08-16.q3hd.bradleybee.0.flac1644 nin2014-08-21.marcsounds.mh.0.flac1644 nin2014-08-22.mk41.blg.0.flac1644 nin2014-08-24.ccm4.anonymous.0.flac1644 nin2014-08-24.ecm77b.ak.0.flac2448 nin2014-08-25.mk41.blg.0.flac1644
ALACへの変換はffmpegを使う。インストール方法と使い方は下記を参照した。
http://skalldan.wordpress.com/2012/10/16/mac-os-x-で-flac-を-alac-に変換する/
$ for i in *.flac; do ffmpeg -i "$i" -acodec alac "`basename "$i" .flac`.m4a"; done
たまにalacへの変換がうまくいかないときはmp3へ。
$ for i in *.flac; do ffmpeg -i "$i" -acodec libmp3lame "`basename "$i" .flac`.mp3"; done
最初は全曲やろうかと思ったけど、録音状態が良さそうなものを適当に選んで変換した。
2014 nin2014-02-25.iem-aud.xavelrecords.0.flac1644 →ALACに変換 nin2014-02-26.iem-aud.newtattoo.0.flac1644 →MP3に変換 nin2014-02-28.iem-aud.newtattoo.0.flac1644 →ALACに変換 nin2014-04-05.sbd.thebang-cynicmuse.0.acc62 →もともとALAC
2013、2009の音源もやってみた。
2013 nin2013-07-26.sbd.cmorris.0.mp3192 もともとMP3 nin2013-09-01.sbd.thebang.0.acc253 もともとALAC 2009 nin2009-08-08.silver.onlythingthatsreal.0.flac1644 →ALACに変換
Macでハイレゾ音源を聴き比べてみる
出遅れ感がありますがハイレゾについて調べてみる。
まずは手軽にできるやり方としてMacでハイレゾの聴き比べ。
Macでハイレゾ
MacのD/Aコンバータはハイレゾ(96kHz、32bit)に対応しているらしいので、まずはMac上でハイレゾとノーマルの聴き比べをしてみる。
やり方は下記のサイトを参考にした。
http://kotyanlife.info/listening-high-resolution-audio-on-mac/
ハイレゾ音源を入手する
- Nine Inch Nails "slip"
いつも聞いているNine Inch Nailsの音源にハイレゾ版があったので入手。
http://dl.nin.com/theslip
FLACの96kHz、24bit版をダウンロードする。
ハイレゾ音源の再生用のアプリをインストール
VOXというアプリがハイレゾ対応らしいのでMacにインストール。
https://itunes.apple.com/jp/app/vox/id461369673?mt=12
IRKitとHTML(jquery + bootstrap)でカスタムテレビリモコンを作ってみる(その弐)
今日はUI。bootstrapでデザインしてみる。
bootstrapのインストール
下記のページからダウンロードして、css、js、fontのフォルダを/var/www/nas/irkitの下に入れておく。
http://getbootstrap.com
使い方はいろいろなページを参照した。
bootstrapでボタンを作って配置
TVのリモコンように最低限必要なボタンを作ってみた。
電源ON/OFF、地デジ/BS切り替え、チャンネル切り替え、音量調整、あとよく使うチャンネルだけはショートカットボタン。例えば、BS1の場合は通常BSに切り替えてからチャンネル1を押す必要があるが、その2手順をワンボタンで実行できるようにした。普通のリモコンより多少便利。
こっちがUI(HTML)のソース。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Bootstrap 101 Template</title> <!-- Bootstrap --> <link href="css/bootstrap.min.css" rel="stylesheet"> <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> <![endif]--> </head> <body> <div class="container"> <h3>AQUOS TV</h3> <p> <button type="button" id="power" class="btn btn-danger btn-lg">電源</button> </p> <p> <button type="button" id="nhk" class="btn btn-danger btn-lg">NHK</button> <button type="button" id="etv" class="btn btn-success btn-lg">Eテレ</button> <button type="button" id="bs1" class="btn btn-primary btn-lg">BS 1</button> <!--<button type="button" id="bsp" class="btn btn-warning btn-lg">BS P</button>--> </p> <div class="btn-group" align="right"> <button type="button" id="db" class="btn btn-primary btn-lg">地デジ</button> <button type="button" id="bs" class="btn btn-success btn-lg">BS </button> </div> <p/> <p> <button type="button" id="chan_down" class="btn btn-info btn-lg"><CH</button> <button type="button" id="chan_up" class="btn btn-info btn-lg">CH></button> <button type="button" id="vol_down" class="btn btn-info btn-lg"><音量</button> <button type="button" id="vol_up" class="btn btn-info btn-lg">音量></button> </p> <p> <div class="btn-group"> <button type="button" id="subtitle" class="btn">字幕</button> </div> </p> </div> <!-- jQuery (necessary for Bootstrap's JavaScript plugins) --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <!-- Include all compiled plugins (below), or include individual files as needed --> <script src="js/bootstrap.min.js"></script> <script src="remote.js"></script> </body> </html>
こっちが通信側(JavaScript)のソース。
var CODE_POWER = "7000,3200,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,2400,920,720,920,2400,920,720,920,2400,920,2400,920,2400,920,2400,920,720,920,720,920,720,920,2400,920,720,920,2400,920,720,920,720,920,2400,920,720,920,720,920,720,920,720,920,2400,920,2400,920,720,920,2400,920,720,920,720,920,720,920,2400,920,720,920,720,920,720,920,2400,920,720,920,2400,920,2400,920,140000"; var CODE_DB = "7000,3200,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,2400,920,720,920,2400,920,720,920,2400,920,2400,920,2400,920,2400,920,720,920,720,920,720,920,2400,920,720,920,2400,920,720,920,720,920,2400,920,720,920,720,920,720,920,2400,920,720,920,720,920,2400,920,720,920,720,920,720,920,2400,920,720,920,2400,920,720,920,720,920,720,920,720,920,720,920,2400,920,140000"; var CODE_BS = "7000,3200,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,2400,920,720,920,2400,920,720,920,2400,920,2400,920,2400,920,2400,920,720,920,720,920,720,920,2400,920,720,920,2400,920,720,920,720,920,2400,920,720,920,720,920,720,920,720,920,2400,920,720,920,2400,920,720,920,720,920,720,920,2400,920,720,920,2400,920,720,920,720,920,2400,920,2400,920,720,920,2400,920,140000"; var CODE_CHAN_1 = "7000,3200,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,2400,920,720,920,2400,920,720,920,2400,920,2400,920,2400,920,2400,920,720,920,720,920,720,920,2400,920,720,920,2400,920,720,920,720,920,2400,920,720,920,720,920,720,920,720,920,2400,920,2400,920,2400,920,720,920,720,920,2400,920,720,920,720,920,2400,920,720,920,720,920,2400,920,2400,920,720,920,720,920,140000"; var CODE_CHAN_2 = "7000,3200,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,2400,920,720,920,2400,920,720,920,2400,920,2400,920,2400,920,2400,920,720,920,720,920,720,920,2400,920,720,920,2400,920,720,920,720,920,2400,920,720,920,720,920,720,920,2400,920,2400,920,2400,920,2400,920,720,920,720,920,2400,920,720,920,720,920,2400,920,720,920,720,920,720,920,2400,920,720,920,720,920,140000"; var CODE_CHAN_3 = "7000,3200,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,2400,920,720,920,2400,920,720,920,2400,920,2400,920,2400,920,2400,920,720,920,720,920,720,920,2400,920,720,920,2400,920,720,920,720,920,2400,920,720,920,720,920,720,920,720,920,720,920,720,920,720,920,2400,920,720,920,2400,920,720,920,720,920,2400,920,720,920,720,920,720,920,720,920,2400,920,2400,920,140000"; var CODE_CHAN_7 = "7000,3200,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,2400,920,720,920,2400,920,720,920,2400,920,2400,920,2400,920,2400,920,720,920,720,920,720,920,2400,920,720,920,2400,920,720,920,720,920,2400,920,720,920,720,920,720,920,720,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,720,920,2400,920,720,920,720,920,720,920,720,920,720,920,2400,920,140000" var CODE_CHAN_UP = "7000,3200,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,2400,920,720,920,2400,920,720,920,2400,920,2400,920,2400,920,2400,920,720,920,720,920,720,920,2400,920,720,920,2400,920,720,920,720,920,2400,920,720,920,720,920,720,920,2400,920,720,920,720,920,720,920,2400,920,720,920,720,920,720,920,2400,920,720,920,720,920,720,920,720,920,2400,920,720,920,2400,920,140000"; var CODE_CHAN_DOWN = "7000,3200,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,2400,920,720,920,2400,920,720,920,2400,920,2400,920,2400,920,2400,920,720,920,720,920,720,920,2400,920,720,920,2400,920,720,920,720,920,2400,920,720,920,720,920,720,920,720,920,2400,920,720,920,720,920,2400,920,720,920,720,920,720,920,2400,920,720,920,720,920,720,920,2400,920,720,920,720,920,2400,920,140000"; var CODE_VOL_UP = "7000,3200,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,2400,920,720,920,2400,920,720,920,2400,920,2400,920,2400,920,2400,920,720,920,720,920,720,920,2400,920,720,920,2400,920,720,920,720,920,2400,920,720,920,720,920,720,920,720,920,720,920,2400,920,720,920,2400,920,720,920,720,920,720,920,2400,920,720,920,720,920,720,920,2400,920,2400,920,2400,920,2400,920,140000"; var CODE_VOL_DOWN = "7000,3200,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,2400,920,720,920,2400,920,720,920,2400,920,2400,920,2400,920,2400,920,720,920,720,920,720,920,2400,920,720,920,2400,920,720,920,720,920,2400,920,720,920,720,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,720,920,720,920,2400,920,720,920,720,920,720,920,720,920,2400,920,2400,920,2400,920,140000"; var CODE_SUBTITLE = "7000,3200,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,720,920,2400,920,2400,920,720,920,2400,920,720,920,2400,920,2400,920,2400,920,2400,920,720,920,720,920,720,920,2400,920,720,920,2400,920,720,920,720,920,2400,920,720,920,720,920,720,920,2400,920,2400,920,2400,920,720,920,720,920,2400,920,2400,920,720,920,720,920,2400,920,720,920,720,920,720,920,720,920,720,920,2400,920,140000"; function ir_doit(ir_code){ var message = '{"freq":38,"format":"raw","data":[' + ir_code + ']}'; $.ajax({ type : "POST", url : "http://192.168.0.2/messages", data : message, async : false, complete : function(jqxhr, status) { console.log("complete: ", jqxhr, status); } }); }; $(function() { $("#power").click(function() { ir_doit(CODE_POWER); }); $("#db").click(function() { ir_doit(CODE_DB); }); $("#bs").click(function() { ir_doit(CODE_BS); }); $("#nhk").click(function() { ir_doit(CODE_DB); ir_doit(CODE_CHAN_7); }); $("#etv").click(function() { ir_doit(CODE_DB); ir_doit(CODE_CHAN_2); }); $("#bs1").click(function() { ir_doit(CODE_BS); ir_doit(CODE_CHAN_1); }); $("#bsp").click(function() { ir_doit(CODE_BS); ir_doit(CODE_CHAN_3); }); $("#chan_up").click(function() { ir_doit(CODE_CHAN_UP); }); $("#chan_down").click(function() { ir_doit(CODE_CHAN_DOWN); }); $("#vol_up").click(function() { ir_doit(CODE_VOL_UP); }); $("#vol_down").click(function() { ir_doit(CODE_VOL_DOWN); }); $("#subtitle").click(function() { ir_doit(CODE_SUBTITLE); }); });