Quantcast
Channel: mattintosh note
Viewing all 878 articles
Browse latest View live

iPhone を Raspberry Pi のリモートスピーカーにする

$
0
0

Raspberry Pi の音声出力を RTP(Real-time Transport Protocol)で同一ネットワーク上のデバイスに転送する。今回は X11 Forwarding を使って Raspberry Pi 上で実行している Chromiumの音声を iPhoneで再生できるようにしてみた。


pulseaudioが起動していなければ起動しておく。pactl load-module module-rtp-send port=12345でリニア PCM で送信することもできるけど、無線環境が良くないとブツブツ切れてしまうので、この後にエンコーダを経由させる。

pulseaudio --start

FFmpegを使用する場合

入力フォーマットを -f pulseで指定し、入力デバイスは -i ''-i 0で指定する。出力フォーマットを -f rtp_mpegtsで指定しておかないとクライアント側で SDP ファイルを要求されるかもしれない。

ffmpeg -f pulse -i''-c:a libmp3lame -f rtp_mpegts rtp://224.0.0.56:12345

VLCを使用する場合

入力デバイスに pulse://0を指定する。

cvlc pulse://0--sout='#transcode{acodec=mp3}:rtp{mux=ts,dst=224.0.0.56,port=12345}'

iPhoneで RTP ストリームを開く。ここでは VLCを使う。

メニューの "Network" -> "Network Stream"開く。

f:id:mattintosh4:20160102171417p:plain:h480

rtp://{アドレス}:{ポート}を入力したら "Open Network Stream"を開く。

f:id:mattintosh4:20160102171426p:plain:h480

Raspberry Pi 上のサウンドが iPhoneで再生される。

f:id:mattintosh4:20160102171432p:plain:h480

VLCはバックグラウンドで動作してくれるので画面ロックしてもサウンドはそのまま再生される。

f:id:mattintosh4:20160102171437p:plain:h480


Chromiumにかかわらず、Raspberry Pi 上で Pulse Audio を使っているものであればすべて iPhone側で再生することができるので、VLCなんかを実行させておいてジュークボックス代わりに使うこともできる。

iPhone側は Bluetoothアダプタのような感じになる。一番いいのは Pulse Audio の module-rtp-sendで直接受信することなんだけど、端末のスペック不足なんだか、うちの無線LAN環境がしょぼいのかイマイチ帯域が安定しない…。

VNCだと普通音が鳴らないけどこの方法だとお音声ありでゲームもできるかなぁ。


Arch Linux ARM で hostapd を使って無線LANアクセスポイントを作成する

$
0
0

レンタルで借りている回線終端装置兼無線LANルータの無線が RTP 通信をブチブチ切ってしまうので Raspberry Pi をアクセスポイントにした。

今回使用した無線LANアダプタは手元にあった以下の2種類。以前、試しにと買ってみたものだが結局ギガビットイーサネットアダプタを購入したので放置していた。どちらも RTL8192cu が使われている(たしか dkms-8192cuを入れたような…)。

  • Logitec LAN-WH300NU2
  • Planex GW-USNANO2A

hostapdパッケージをインストール。

pacman -S hostapd

今回は「無線ルータ」ではなく「無線アクセスポイント」を作成するのでブリッジ接続になる。ブリッジ接続を作成する方法はいくつかあるらしいが、Raspberry Pi 2 Model B+ にインストールしている Arch Linux(armv7l)では systemd で作成できるようなのでそちらの方法を選択した。

現在の Raspberry Pi の構成は有線LAN×2、無線LAN×1で、ブリッジとして使うのは eth1wlan0

まず、起動時に自動でブリッジインタフェイスを作成させるために /etc/systemd/network/br0.netdevを用意する。このあたりのことは man systemd.networkを読めば例などが載っている。

[NetDev]
Name=br0
Kind=bridge

次に br0用の /etc/systemd/network/br0.networkを用意する。IP アドレスは固定にしているが DHCPでも恐らく問題ない。

[Match]
Name=br0

[Network]
Address=192.168.1.100/24
Gateway=192.168.1.1

次に /etc/systemd/network/eth1.network/etc/systemd/network/wlan0.networkを作成する。中身は [Match]セクションの Nameの値が異なるだけ。

[Match]
Name=eth1

[Network]
Bridge=br0
[Match]
Name=wlan0

[Network]
Bridge=br0

ネットワークを再起動(した気がする)が、再起動した方が手っ取り早いかもしれない。

sudo systemctl restart systemd-network

再起動してみて br0が作成されていれば hostapdのテストを行う。設定ファイルのサンプルが /usr/share/doc/hostapdに収録されているので hostapd.confを適当な場所にコピーする。

cp /usr/share/doc/hostapd/hostapd.conf ~/

interfacebridge部分を環境に合わせる。これで準備は出来たのだけど、8192cu の場合、通常の hostapdが 8192cu に対応していないらしい…。色々調べた結果 http://www.adafruit.com/downloads/adafruit_hostapd.zipで置き換えて、driver=rtl871xdrvを指定すればいいらしい。

interface=wlan0
bridge=br0
# RTL8192CUの場合
driver=rtl871xdrv

hostapdを起動する。設定ファイルに誤りがある場合は場所を教えてくれる。

sudo hostapd ~/hostapd.conf

適当なデバイスで接続して問題なく接続できれば hostapdを終了する。

誰でも気軽に接続できる状態なのでこれはこれで使い道があるかもしれないが、セキュリティの設定をしていく。WPA のパスワードを hostapd.confに直接書くこともできるが、ここでは wpa_passphraseを使ってパスワードを作成する。SSIDPASSWORDは任意。ちなみに SSIDは日本語でもOK。

wpa_passphrase SSID PASSWORD

hostapd.confを編集する。以下はコメントアウトされていない部分だけを引っこ抜いたもの。(SSIDとパスワードはダミー)

interface=wlan0
bridge=br0
driver=rtl871xdrv
logger_syslog=-1
logger_syslog_level=2
logger_stdout=-1
logger_stdout_level=2
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
ssid=おやき
hw_mode=g
channel=1
beacon_int=100
dtim_period=2
max_num_sta=255
rts_threshold=2347
fragm_threshold=2346
macaddr_acl=0
auth_algs=3
ignore_broadcast_ssid=0
wmm_enabled=1
wmm_ac_bk_cwmin=4
wmm_ac_bk_cwmax=10
wmm_ac_bk_aifs=7
wmm_ac_bk_txop_limit=0
wmm_ac_bk_acm=0
wmm_ac_be_aifs=3
wmm_ac_be_cwmin=4
wmm_ac_be_cwmax=10
wmm_ac_be_txop_limit=0
wmm_ac_be_acm=0
wmm_ac_vi_aifs=2
wmm_ac_vi_cwmin=3
wmm_ac_vi_cwmax=4
wmm_ac_vi_txop_limit=94
wmm_ac_vi_acm=0
wmm_ac_vo_aifs=2
wmm_ac_vo_cwmin=2
wmm_ac_vo_cwmax=3
wmm_ac_vo_txop_limit=47
wmm_ac_vo_acm=0
ieee80211n=1
eapol_key_index_workaround=0
eap_server=0
own_ip_addr=127.0.0.1
wpa=2
wpa_psk=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP

設定ファイルを所定の位置に移動。

sudo mv ~/hostapd.conf /etc/hostapd

権限を変更しておく。

sudo chown root:root /etc/hostapd/hostapd.conf
sudo chmod0600 /etc/hostapd/hostapd.conf

再起動したときに hostadp自動起動するようにしておく。

sudo systemctl enable hostapd
sudo systemctl start hostapd

前日に RTP で音楽のストリーミングをしていたときはブチブチ切れていたけど、親機を Raspberry Pi に変更したら安定するようになった。ただ、極端に負荷をかけるとネットワークが切れることがあるようだが、タブレットに地デジのデータなどを飛ばしていたりするくらいなら大丈夫っぽい。

NASVPNサーバに無線アクセスポイントと大活躍の Raspberry Pi。そろそろ1年だし新しいモデル出たりしないかなぁ…なんて。

Raspberry Pi 2 Model B (1)

Raspberry Pi 2 Model B (1)

Arch Linux ARM Chromium で Segmentation fault (core dumped)

$
0
0

Raspberry Pi 2 Model B で動かしている Chromiumがアップデートでちょいちょい起動しなくなることがある。これまでは pacman -Uでダウングレードしたりしてたけど、今回はそれでは直らず、再び起動できるようになるまで時間がかかってしまった。

多分、手っ取り早く解決するなら chromium --disable-gpuchromium --ignore-gpu-blacklistで起動すればよい。それでも起動しなければ ~/.config/chromium~/.cache/chromiumを削除してみる。

また、いつぞやのバージョンから PepperFlashがロードされなくなってしまった問題は ~/.config/chromium-flags.confPepperFlashをロードするための記述をしておけばよい。(※PepperFlashについては Chromiumが自分で探すようになっているが、うちの環境ではロードしてくれないので手動で指定している)

--ignore-gpu-blacklist
# OR#--disable-gpu                                                                                                                                          
--ppapi-flash-path=/usr/lib/PepperFlash/libpepflashplayer.so                                                                                           
--ppapi-flash-version=12.0.0.77

chromium-flags.confについて、もう少し詳しく書くなら ~/.config/chromium/chromium-flags.confではなく、~/.config/chromium-flags.confであること。また $XDG_CONFIG_HOME/chromium-flags.confでもある。

https://wiki.archlinux.org/index.php/Chromium/Tips_and_tricks#Making_flags_persistent


また、microSD の劣化を抑えるために、Chromiumのキャッシュを tmpfs に置くことにした。/etc/fstabに以下のように記述しておけば tmpfs にキャッシュが溜まる。(ついでに再起動するごとに Chromiumのキャッシュが消える)。

tmpfs /home/alarm/.cache/chromium tmpfs nodev,nosuid,size=128M 00

X over SSH を使わずに X アプリケーションを呼び出す

$
0
0

X アプリケーションをリモートから呼び出すというと X over SSHが定番です(思ってます)が、非力な Raspberry Pi にとっては暗号化もそれなりに負荷になります。

ssh -X 192.168.1.254 chromium

「そもそも家で使うなら暗号化なぞ必要無いのでは?」ということで色々試してみました。

Mac OS<- Linux

前提として Mac OS側に X 環境(XQuartz.app など)が必要です。

XQuartz.app を起動したあとに xterm などから ~/.Xauthorityに記述されている COOKIEを送る必要があります。ここでは IP アドレスが以下のようになっているとして進めます。

ホスト名OSIP アドレスディスプレイ
macMac OS192.168.1.2:0
rpiLinux192.168.1.254none

まずは、XQuartz.app の「環境設定」で認証を有効にしておきます。はじめての場合は XQuartz.app を再起動します。

https://lh3.googleusercontent.com/-BDLEa1pRCy8/VpkG31Hc0wI/AAAAAAAANN0/r7_gBM1PJpI/s800-Ic42/35fc3c18776a60c18ba52253bfb309ea.png

COOKIEの登録

次に、Mac OS側の COOKIEを X アプリケーションを実行するマシンへ送ります。

COOKIEの送り方(登録の仕方)はいくつかありますが、簡単なのは extractコマンドで標準入力から取り込む方法です。extract -で標準出力へ出力したものを merge -で受け取ります。

mac$ xauth extract - 192.168.1.2:0 | ssh 192.168.1.254 xauth merge -

xauth listで表示したものをコピーして送信先で xauth addする方法もあります。

mac$ xauth list
192.168.1.2:0 MIT-MAGIC-COOKIE-1 0123456789ABCDEFGHIJKLMNOPQRSTUV
mac$ ssh 192.168.1.254
rpi$ xauth add 192.168.1.2:0 . 0123456789ABCDEFGHIJKLMNOPQRSTUV

listコマンドで確認して登録されていれば OK です。

rpi$ ssh 192.168.1.254 xauth list
192.168.1.2:0 MIT-MAGIC-COOKIE-1 0123456789ABCDEFGHIJKLMNOPQRSTUV

COOKIEを新たに作る場合は generateコマンドや mcookieコマンドで作成ができます。ディスプレイ名の次にはプロトコル名がきますが、 .にしておくと暗黙的に MIT-MAGIC-COOKIE-1としてくれます。

generateの場合例

xauth generate :1 .

mcookieの場合の例

xauth add :1 . `mcookie`

COOKIEを送ったらサーバにログインしてアプリケーションを呼び出します。

SSHでログインして、DISPLAY環境変数Mac OSのディスプレイを指定してアプリケーションを実行するだけです。ここでは gnome-system-monitorを起動します。トンネリングはしないので SSHオプションの -X-Yは必要ありません。

mac$ ssh 192.168.1.254
rpi$ DISPLAY=192.168.1.2:0 gnome-system-monitor

sshの引数にコマンドを指定しても実行できます。

mac$ ssh 192.168.1.254 DISPLAY=192.168.0.2:0 gnome-system-monitor`

XQuartz.app の場合は Quartz ウィンドウマネージャが起動しているのでアプリケーションを実行するだけでいいのですが、ウィンドウマネージャが起動していない環境の場合はウィンドウマネージャも起動しておく必要があるかもしれません。

lnx$ ssh 192.168.1.254 'export DISPLAY=192.168.1.3:1; metacity & gnome-system-monitor'

Mac OS側で Raspberry Pi の状況をグラフィカルにチェックすることができます。この程度の描写なら 1MB/s ですが、頻繁に動くものとなると 10MB/s を超えるのである程度帯域は必要です。

https://lh3.googleusercontent.com/-Xcg84r7sxBk/Vpj-70YPJgI/AAAAAAAANN0/c4Hv7LNereU/d-Ic42/5390fff9b99739dfadb45c932ff8a37d.png

ディスプレイは複数のマシンに共有させることができます。ここでは左に Raspberry Pi 2 Model B のシステムモニタ、右に Raspberry Pi Model B+ のシステムモニタを表示しています。

https://lh3.googleusercontent.com/-vewW9oy0onU/VpnfT5sTN2I/AAAAAAAANOo/H6hQ2-4wVkE/d-Ic42/88f6f37abb49b0b8e7470b8d0b20eeeb.png

Linux<- Linux

LinuxMac<- Linuxと同じようにして接続ができますが、XQuartz.app とやりとりするよりは少しわかりづらいかもしれません。

例えば、COOKIEを正しく登録しても「Invalid MIT-MAGIC-COOKIE-1 key」と表示され、うまく接続できないことがあります。

rpi$ DISPLAY=192.168.1.2:1 xterm
Invalid MIT-MAGIC-COOKIE-1 keyxterm: Xt error: Can't open display: 192.168.1.2:1

これはうちの環境の話ですが、Xnest や Xephyr で新しく起動したウィンドウに接続できなくて困っていたのですが、KDEの場合は xauth を実行した際に ~/.Xauthorityではなく /tmp/kde-USERNAME/xauth-1000-_0というファイルを使用していることが原因でした。

XAUTHORITY環境変数がセットされている環境で Xnest や Xephyr にアプリケーションを呼び出す場合は -authオプションでファイルを指定する必要があるかもしれません。

Xnest :1 -auth $XAUTHORITY
Xephyr :2 -auth $XAUTHORITY

もしくは -ac(disable access control restrictions)オプションで認証を無効にする方法もあります。この方法は COOKIEを登録する必要がありません(セキュリティには注意が必要です)。

Xnest :1 -ac
Xephyr :2 -ac

ここまで ssh -Xとすればいいだけの問題をわざわざ xauth を使ったりしていたのは Raspberry Pi の画面出力を Xnest や Xephyr で引っ張ってくるためでした。自分の環境は Intelチップの KDE環境なんですが、なんか Raspberry Pi と相性悪い?のか、:0に表示するより Xnest とかに表示した方が動きがいいんですよね…。

とりあえず艦これもそこそこ動くようになったので今回の作業はここまで。

ffmpeg \-video_size 1280x720 -framerate30-f x11grab -draw_mouse0-i :0+1446,100-f pulse -i0\-c:v libx264 -q:v -1-pix_fmt yuv420p -preset ultrafast -x264optsbframes=2:cabac=1:open_gop=1\-c:a aac -strict experimental -b:a 320k \-movflags faststart out.mp4

Raspberry Pi でワイヤレスディスプレイを作る

$
0
0

先日、ジャンクで良いディスプレイが手に入ったので長年使っていた Princeton PTFBHF-19W をメインPCから取り外した。デスクトップをメインに使っていた頃にデュアルディスプレイ環境用として2台同時購入して、ノートPCに切り替えてから1台余っていたが、これで2台とも余ってしまうことになった。

手放すのもなんとなくもったいないので Raspberry Pi 1 Model B+ を使って X Window System用のワイヤレスディスプレイとして使うことにした。

(「ワイヤレスディスプレイ」と言うかどうかは怪しい)

環境

HWOSInterface
メイン汎用機KubuntuWired (1000Mbps)
APRaspberry Pi 2 Model B+Arch Linux ARMWireless
Logitec LAN-WH300NU2 (RTL8192CU / 300Mbps)
X Window ServerRaspberry Pi 1 Model BArch Linux ARMWireless
Planex GW-USNANO2A (RTL8188CUS / 150Mbps)

その前に、以前設定した hostapd の導入手順が若干間違っていたのでやり直した。

802.11b/g/n 系の無線LANアダプタで使われている Realtek RTL8192CU は純正の hostapd に対応していない。RealtekLinux用ドライバのソースを公開しているので自前でコンパイルすればいいのだが、手を抜いてバイナリだけ拾ってきてしまった。そのため、純正の hostapd.conf の設定が RTL8192CU に適した状態になっていなかった。

Raspberry Pi 2 Model B 上で RTL8192CU 用のドライバをコンパイルする。ドライバは Realtekのページからダウンロードしてくる。

http://www.realtek.com.tw/downloads/downloadsView.aspx?Langid=4&PNid=48&PFid=48&Level=5&Conn=4&DownTypeID=3&GetDown=false&Downloads=true#2772

ダウンロードしたファイルを解凍する。ZIP なのが解せない。

unzip 0001-RTL8188C_8192C_USB_linux_v4.0.2_9000.20130911.zip

なんか色々入っているが、とりあえず関連するのはこのあたりか。

RTL8188C_8192C_USB_linux_v4.0.2_9000.20130911
└── wpa_supplicant_hostapd
    ├── rtl_hostapd_2G.conf
    ├── wpa_supplicant_hostapd-0.8_rtw_r7475.20130812
    │   └── hostapd
    │       ├── Android.mk
    │       ├── bsd_hostapd.conf
    │       ├── ChangeLog
    │       ├── config_file.c
    │       ├── config_file.h
    │       ├── ctrl_iface.c
    │       ├── ctrl_iface.h
    │       ├── defconfig
    │       ├── dump_state.c
    │       ├── dump_state.h
    │       ├── eap_register.c
    │       ├── eap_register.h
    │       ├── eap_testing.txt
    │       ├── hlr_auc_gw.c
    │       ├── hlr_auc_gw.milenage_db
    │       ├── hostapd.8
    │       ├── hostapd.accept
    │       ├── hostapd_cli.1
    │       ├── hostapd_cli.c
    │       ├── hostapd.conf
    │       ├── hostapd.deny
    │       ├── hostapd.eap_user
    │       ├── hostapd.radius_clients
    │       ├── hostapd.sim_db
    │       ├── hostapd.vlan
    │       ├── hostapd.wpa_psk
    │       ├── logwatch
    │       ├── main.c
    │       ├── Makefile
    │       ├── nt_password_hash.c
    │       ├── README
    │       ├── README-WPS
    │       ├── src -> ../src
    │       └── wired.conf
    └── wpa_supplicant_hostapd-0.8_rtw_r7475.20130812.tar.gz

階層を降りていく途中で RTL8192CU 用の hostapd.conf を拾う。もともとある hostapd.conf はバックアップ。パスがかなり長くなるので PS1にフルパスを表示するようにしている場合は変更しておいた方が楽かもしれない。

mv /etc/hostapd/hostapd.conf{,.orig}cd RTL8188C_8192C_USB_linux_v4.0.2_9000.20130911/wpa_supplicant_hostapd
cp rtl_hostapd_2G.conf /etc/hostapd/hostapd.conf

デフォルトだと設定は以下のようになっているので使う環境に合わせて変更しておく。

  • SSID: rtwap
  • channel: 6
  • wpa_passphrase 87654321

hostapd を使用した簡単な方法で WiFi に強力な暗号化を実装するによれば、平文パスワードは計算負荷が高くなるため wpa_passphraseで暗号化鍵を生成し、そちらを使う方がよいそうだ。hostapd.confwpa_passphrase行をコメントアウトして wpa_psk行を追加する。(以下は例)

$ wpa_passphrase rtwap 87654321 | printf 'wpa_%s\n' `grep '[^#]psk'`
wpa_psk=65a918de53333a864d822976d8664f6661985c1cac62e1db628ea445233c5c73

さらに同じ階層にある TAR を解凍し、hostapd/まで降りて make。Raspberry Pi 2 Model B でだいたい30秒くらい。

tar xf wpa_supplicant_hostapd-0.8_rtw_r7475.20130812.tar.gz
cd wpa_supplicant_hostapd-0.8_rtw_r7475.20130812
cd hostapd
make

もともとあったものをバックアップして出来上がったバイナリをインストールする。

mv /usr/bin/hostapd{,.orig}mv /usr/bin/hostapd_cli{,.orig}
cp hostapd hostapd_cli /usr/bin

これで hostapd は最適な状態(?)になった。


wpa_supplicant は純正のバイナリで使用することができるが、そのままのドライバでは動作しないため /usr/lib/systemd/system/wpa_supplicant@.serviceExecStart行に -Dwextを追加する。

[Unit]
Description=WPA supplicant daemon (interface-specific version)
Requires=sys-subsystem-net-devices-%i.device
After=sys-subsystem-net-devices-%i.device
Before=network.target
Wants=network.target

# NetworkManager users will probably want the dbus version instead.

[Service]
Type=simple
ExecStart=/usr/bin/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-%I.conf -i%I -Dwext

[Install]
Alias=multi-user.target.wants/wpa_supplicant@%i.service

あとは /etc/wpa_supplicant/wpa_supplicant-wlan0.confを作成しておいて systemctl enable wpa_supplicant@wlan0としておく。

network={
        ssid="rtwap"
        #psk="87654321"
        psk=65a918de53333a864d822976d8664f6661985c1cac62e1db628ea445233c5c73
}

んで、ようやく X Window Server の設定。

autologin にしておこうかなぁと思ったけど、X はとりあえず手動で立ち上げることにした。

普通に xinitとしてしまうと /etc/X11/xinit/xserverrcによって -nolisten tcpになってしまう。

#!/bin/shexec /usr/bin/X -nolisten tcp "$@"

なので ~/.xserverrcとしてコピーして TCPのリスニングを有効にしておく。

cp /etc/X11/xinit/xserverrc ~/.xserverrc
#!/bin/shexec /usr/bin/X -listen tcp "$@"

これで xinitとすれば6000番が開いた状態になる(netstatコマンドで確認する場合、--numeric-portsオプションがない場合は :x11表記になるので grep 6000とかやっても出てこない)。

$ netstat -t4 --listen
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 *:x11                   *:*                     LISTEN

~/.xinitrcは最小限に DPMS の無効化と dwmのみ。ワイヤレスモニター的な感じで使う予定なので電源は手動で切るほうが都合がいい。

xset -dpms
xset s off
exec /usr/bin/dwm

ぼちぼち出来上がったので無線強度の確認。ディスプレイと Raspberry Pi 1 Model B を持って玄関へ。PC用の3ピンケーブル(?)って根本の部分から電源分岐とか出来たりしないですかねぇ。そうなると Raspberry Pi の電源確保が非常に楽なのだけど。使い道がなかったタッチパッド付きワイヤレスキーボードの使い道が出来たのはよかったかも。

Raspberry Pi 1 Model B 用の Google Chrome / Chromiumは提供されていない(わけではないと思う)けど、メインマシンから呼び出しているので YouTubeなんかも見れる。ただ、Google Chrome / Chromiumは母艦で起動していると多重起動しないようになっているのでダミーのプロファイルディレクトリを --user-data-dir=/path/to/dirで適当に作成してあげる必要がある。

なんとなくキッチンのラックに置いてみた。艦これも Raspberry Pi では少々厳しいけど X86マシンで実行しているので普通にプレイできる(快適に、とは言えないが)。

あとは VirtualBoxとかも引っ張ってくれば Raspberry Pi で Windows XPやら Windows 7を動かしたりも出来たり…(何でもアリやないか)。

Windows XP on #RaspberryPi ssh -X example.local vboxmanage startvm WinXP ╭( ・ㅂ・)و ̑̑

Makoto Yoshidaさん(@mattintosh4)が投稿した写真 -


何かの監視用モニターとして使いたいのだけど作業机が狭いのでいまのところはキッチンに…。壁掛けにしたいなぁ。

Raspberry PiのルートパーティションをUSBデバイスに移動する

$
0
0

Raspberry Pi 1 Model B+ に取り付けていた microSD を取り替えるにあたって、ルートパーティションの内容を USB メモリに移動した。USB にルートパーティションを作成する理由は「ただやってみたかったから」。

  • 前) 16GB microSD
  • 後) 2GB microSD + 16GB USB memory Stick

作業は別のマシンで行う。

一般的(?)に microSD(mmcbulk0)の内容を複製するには ddを使うことが多い(と思う)が、2GB 程度しか使ってない 16GB のパーティションddでコピーするのは時間の無駄なので cpioによるコピーを使う。

構成はこんな感じ。まずはルートパーティション用の USB フラッシュメモリから。

/dev/
|
+-- sdb/ (2GB microSD)
|   |
|   +-- sdb1 (mmcblk0p1 / FAT32)
|   |
|   +-- sdb2 (mmcblk0p2 / ext4)
|
+-- sdc (16GB USB memory stick)
|
+-- sdd (2GB microSD)

ルートパーティションを独立させる場合、GPT でもマウントできるっぽいので sgdiskで作成。

sgdisk -Z /dev/sdc
sgdisk -n1::: /dev/sdc
mkfs.ext4 /dev/sdc1

続いてルートパーティションのデータを移動する。既にファイルシステムは出来上がっているので resize2fsをする必要はない。

cd /tmp
mkdir src dst
mount /dev/sdb2 src
mount /dev/sdc1 dst
cd src
find . -depth -print | cpio -pdmu ../dst
cd ..
sync
umount src dst

次にブートパーテイション。こっちは MBR

sgdisk -Z /dev/sdd
fsdisk /dev/sdd <<!on+100Mtcw!
mkfs.vfat /dev/sdd

ルートパーティションと同じようにブートパーティションをコピーする。

mount /dev/sdb1 src
mount /dev/sdd1 dst
cd src
find . -depth -print | cpio -pdmu ../dst
cd ..

/boot/cmdline.txtroot=を書き換える。root=/dev/mmcblk0p2root=/dev/sda1とする。

vim dst/boot/cmdline.txt
+++ src/boot/cmdline.txt   2016-01-30 23:26:08.000000000 +0900--- dst/boot/cmdline.txt   2016-01-30 23:26:17.000000000 +0900@@ -1 +1 @@-root=/dev/mmcblk0p2 rw rootwait console=ttyAMA0,115200 console=tty1 selinux=0 plymouth.enable=0 smsc95xx.turbo_mode=N dwc_otg.lpm_enable=0 kgdboc=ttyAMA0,115200 elevator=noop+root=/dev/sda1 rw rootwait console=ttyAMA0,115200 console=tty1 selinux=0 plymouth.enable=0 smsc95xx.turbo_mode=N dwc_otg.lpm_enable=0 kgdboc=ttyAMA0,115200 elevator=noop

アンマウントして Raspberry Pi に差し替える。

umount src dst

Raspberry Pi に新しい microSD と USB メモリをセットして起動する。

この方法は欠点があり、ストレージデバイスが接続されている場合、必ずしもルートパーティションを含んだデバイスが sdaにはならないということがある(USB メモリと HDD であれば USB メモリの方が先に認識されるだろうが)。

root=UUID=による指定方法もあるらしいのだが、Raspberry Pi 2 Model B 移行対応なのか、root=UUID=root=PARTUUID=で指定しても Raspberry Pi 1 Model B+ ではどうしても起動できなかった。

ルートパーティションをUSBメモリに移した。 #RaspberryPi

Makoto Yoshidaさん(@mattintosh4)が投稿した写真 -

で、速くなったのかと言われると微妙で、シングルコアの ARM だとよくわからないのである。た、耐久性重視なんだ…(;´∀`)

HDD だともう少しわかりやすいんだろうけど。


追記:initrd を使用して UUID でマウントできるようにしてみました。

mattintosh.hatenablog.com

Raspberry PiでUUID指定でルートパーティションをマウントする

$
0
0

昨日、Raspberry Pi のルートパーティションを USB メモリに移した話を書いたのですが、やっぱり root=/dev/sda1と指定するのは納得がいかないので root=UUID=で起動できるようにしてみました。

mattintosh.hatenablog.com

まずはちょっとおさらい。

現在の blkidの出力はこんな感じです。(ここでの UUID は uuidgenで書き換えたダミーです)

# sudo blkid
/dev/mmcblk0p1: SEC_TYPE="msdos" UUID="0000-0000" TYPE="vfat" PARTUUID="00000000-00"
/dev/mmcblk0: PTUUID="00000000" PTTYPE="dos"
/dev/sda1: UUID="d505fd00-8573-4681-b34c-a03ffaa40c75" TYPE="ext4" PARTUUID="e7ccba30-0efc-4bee-9c1c-f12f442b5f9e"

/dev/sda1 行に記載されている UUID="d505fd00-8573-4681-b34c-a03ffaa40c75"/boot/cmdline.txtroot=に記載すれば起動できる…らしいのですが、Raspberry Pi 1 Model B+ ではそれだけでは起動できませんでした。

これとは別件(ディスプレイを回転させる方法)で config.txtのマニュアルを読んでいたところ、config.txt内で initramfs を指定できるとのこと。

www.raspberrypi.org

initramfs を指定する方法は2つあり、まず1つ目は ramfsfile=ramfsaddrを指定する方法。

ramfsfile=<filename>
ramfsaddr=<address>

もう1つは initramfsだけで指定する方法があるようです。この場合のみ特殊で、=は使用しません。

initramfs <filename> <address>

今回は後者の initramfsを使用しました。

まずは initrd を作成します。Arch Linux ARM の場合、mkinitcpiomkinitcpioパッケージに含まれています。

mkinitcpio -z gzip -g /boot/initrd.gz

config.txtinitramfs行を追加します。<address>0x00800000なんかを指定するようなのですが、試してみたところうまく割り当てができなかったので followkernelを使うことにしました。

echo initramfs initrd.gz followkernel >>/boot/config.txt

/boot/cmdline.txtを書き換えます。root=UUID=は上の blkidで調べたもの。

root=UUID=d505fd00-8573-4681-b34c-a03ffaa40c75 rw rootwait console=ttyAMA0,115200 console=tty1 selinux=0 plymouth.enable=0 smsc95xx.turbo_mode=N dwc_otg.lpm_enable=0 kgdboc=ttyAMA0,115200 elevator=noop

なお、ルートパーティションを USB メモリに移したときもそうですが、/etc/fstabにルートパーティションの記載はしていません(記載してなくても起動できるようで…)。後々ちゃんと書きますが。

# 
# /etc/fstab: static file system information
#
# <file system> <dir>   <type>  <options>       <dump>  <pass>
/dev/mmcblk0p1  /boot   vfat    defaults        0       0
/swapfile       none    swap    swap            0       0

これで再起動すれば UUID でルートパーティションを探してくれます。

initrd.gz が読み込めていない場合は dmesgにエラーが出力されます。あと、パット見ですが、ルートパーティションの読み込みに関する部分が少し変わっていました。今までは ext2ext3とテストが行われていたのですが、initramfs にしてから一発で ext4と認識してます。

:
[    6.767761] scsi 0:0:0:0: Direct-Access     SanDisk  Ultra USB 3.0    1.00 PQ: 0 ANSI: 6
[    6.785853] sd 0:0:0:0: [sda] 30375936 512-byte logical blocks: (15.5 GB/14.4 GiB)
[    6.807828] sd 0:0:0:0: [sda] Write Protect is off
[    6.816467] sd 0:0:0:0: [sda] Mode Sense: 43 00 00 00
[    6.825209] sd 0:0:0:0: [sda] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
[    6.877905]  sda: sda1
[    6.890652] sd 0:0:0:0: [sda] Attached SCSI removable disk
[    7.587282] EXT4-fs (sda1): mounted filesystem with ordered data mode. Opts: (null)
:

cmdline.txt の記述に間違いがあって起動できなくても microSD の差し替えなしで修正できるのは有り難い…。


さてあとは JACK 環境の構築か…。

Linux同士でオーディオを転送する

$
0
0

ここ数日、「母艦の音を PulseAudio で Raspberry Pi 1 Model B+ で再生する」というのをやっていたけど、ミュージックプレーヤーの2曲目がどうしても再生できないという問題を解決できず…。無線にしているのが悪いのかと思い有線にしてみたり、PulseAudio のモジュールを減らしてみたり追加したり。週末にようやくそれっぽい書き込みをいくつか見つけた。

raspberrypi.stackexchange.com

うーん、なんか Raspberry Pi 1 Model B+ だと難しいような気がしてきた…。

「module-native-protocol-tcp以外にオーディオを転送する方法はあるのか?」

PulseAudio の module-native-protocol-tcpが上手く動かないので他の方法をいくつか検討してみた。

parec

まずは parecpacatの組み合わせ。

module-native-protocol-tcpを手動で行うイメージか。module-native-protocol-tcpの時のようにまったく応答しなくなることはないが、細かく途切れている感じ。parecのデバイスの指定は alsa_output.pci-0000_00_1b.0.analog-stereo.monitorのように指定することもできるが、デバイス番号でも指定ができる。デバイス名は pactl list short | grep monitorなどで調べることができる。

$ parec -d 0 | ssh 192.168.1.100 pacat

次に parecaplayの組み合わせ。先ほどに比べて音切れは無く、良い感じ。ただ、若干タイムラグがある。aplay-f cd-f S16_LE -c2 -r44100の略式。

$ parec -d 0 | ssh 192.168.1.100 aplay -t raw -f cd -
Playing raw data 'stdin' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo

parecで母艦の音をキャプチャする場合、母艦のスピーカーでもそのまま音が再生されるので alsamixierなどでスピーカーの音をオフにしておいた方が都合がいいことがあるかもしれない。

f:id:mattintosh4:20160202150624p:plain

module-tunnel-sink

リモートのサウンドデバイスを母艦のデバイスとして扱える(?)。サーバを Raspberry Pi とした場合、母艦に bcm2835 ALSA Analog Stereo を接続できる。母艦に存在していることになっているので音量調整なんかもできる。

f:id:mattintosh4:20160202151517p:plain

まず、サーバ(Raspberry Pi)側で module-native-protocol-tcpを有効にしておく。認証方法の説明についてはここでは省略する。

load-module module-native-protocol-tcp auth-anonymous=1

クライアント側で module-tunnel-sinkをロードする。また、引数でサーバ側の sink を指定することもできる。

(IP アドレスでは指定できない…?)

$ pacmd load-module module-tunnel-sink server=alarmpi.local

上手く接続されればクライアント側の sink リストに表示される。

$ pacmd list-sinks
:
    index: 1
        name: <tunnel-sink.alarmpi.local>
        driver: <module-tunnel.c>
        flags: NETWORK HW_MUTE_CTRL HW_VOLUME_CTRL LATENCY 
        state: SUSPENDED
        suspend cause: IDLE 
        priority: 0
        volume: 0:  69% 1:  69%
                balance 0.00
        base volume: 100%
        volume steps: 65537
        muted: no
        current latency: 0.00 ms
        max request: 0 KiB
        max rewind: 0 KiB
        monitor source: 3
        sample spec: s16le 2ch 44100Hz
        channel map: front-left,front-right
                     Stereo
        used by: 0
        linked by: 0
        fixed latency: 250.00 ms
        module: 22
        properties:
                device.description = "bcm2835 ALSA Analog Stereo on USERNAME@alarmpi.local"
                tunnel.remote.server = "alarmpi.local"
                device.icon_name = "audio-card"
                tunnel.remote_version = "30"
                tunnel.remote.user = "USERNAME"
                tunnel.remote.fqdn = "alarmpi.local"
                tunnel.remote.description = "bcm2835 ALSA Analog Stereo"

mplayerではデバイスを直接指定することができるので以下のようにして PulseAudio のデバイスを指定できる。

$ mplayer -ao pulse::tunnel-sink.alarmpi.local sound.wav

デバイスを選択出来ないアプリケーションの場合は PULSE_SINK環境変数を使う。

$ PULSE_SINK=tunnel-sink.alarmpi.local speaker-test

母艦で PulseAudio を使っている音声を全て module-tunnel-sink に流すならデフォルトの sink を変えてしまえばよい。この時の sink は名前以外に indexで指定ができる(つまり、set-default-sink 0とすればデフォルトのデバイスに戻る)。list-sinksをインデックスの隣に *が表示されるのでどれが現在のデフォルトかすぐわかる。

$ pacmd set-default-sink tunnel-sink.alarmpi.local
$ pacmd list-sinks
$ pacmd set-default-sink 0

で、肝心の音はどうなのよ、と言うと pacatを使った時とあまり変わらず…。しかもボリューム調整とかしなきゃ音が割れるのでむしろ pacatよりも難しいかもしれない。


とりあえずオーディオ遊びはこの辺まで…。


Arch Linux ARMのディスクイメージを作成する(losetup、kpartx)

$
0
0

Raspberry Pi × Arch Linux ARM で勉強会をやろうと思っていて、当日は受講者にもブートディスクを作成してもらおうと思ったけど、Arch Linux ARM のディスクイメージで頒布されていない。

デモ機が Linuxなら(bsdtarがあれば)何も問題はないのだけど、用意されるのは恐らくすべて Windowsマシン。Windowsではそもそも microSD に複数パーティションを作成することができない(と、記憶している)し、ルートパーティションに使用する ext4ファイルシステムを作成することも怪しいため、TAR.GZ から Arch Linux ARM をインストールすることができない(と、思ってる)。

VirtualBoxなどの仮想マシンを用意してゲスト OS に USB デバイスを接続する…という方法も無くはないが、デモ機すべてに Linux仮想マシンを用意するのも手間がかかる。

そこで、自分の方で Arch Linux ARM のディスクイメージを作成することにした。

イメージファイルの作成

まず、Arch Linux ARM がどれくらいの容量が必要なのか確認する。今回は Raspberry Pi 1 Model B+(armv6)用を使用する。2016年2月2日時点で約 592MB だった(一応、展開して調べたところ約 614MB だったかな)。

$ curl -LO http://archlinuxarm.org/os/ArchLinuxARM-rpi-latest.tar.gz
$ gzip -l ArchLinuxARM-rpi-latest.tar.gz | numfmt --header=1 --field=1,2 --to si
compressed uncompressed ratio uncompressed_name 284M 592M 52.1% ArchLinuxARM-rpi-latest.tar

このサイズであれば 1GB もあれば足りるので 1GB のイメージファイルを作成する。1024 ではなく 1000 で作るけど、メモリ系は実表記より少ないものの方が多いみたいだ。ブートパーティションを差し引いたルートパーティションのサイズは 900MB 程度になり、パッケージを追加すると当然足りなくなるサイズだが、今の御時世 1GB の microSD を手に入れるより 4GB の microSD を入手する方が楽だろうし、resize2fsの練習もできるのでとりあえず 1GB でも十分だろう。

$ fallocate -l 1GB ArchLinuxARM_`date +%Y%m%d`.img

パーティショニング

先程作成したイメージファイルに対して fdiskを実行する。

$ fdisk ArchLinuxARM_20160202.img <<!
o
n



+100M
t
c
n




w
!
Welcome to fdisk (util-linux 2.27.1). Changes will remain in memory only, until you decide to write them. Be careful before using the write command. Command (m for help): Created a new DOS disklabel with disk identifier 0x1fd6017a. Command (m for help): Partition type p primary (0 primary, 0 extended, 4 free) e extended (container for logical partitions) Select (default p): Using default response p. Partition number (1-4, default 1): First sector (2048-1953124, default 2048): Last sector, +sectors or +size{K,M,G,T,P} (2048-1953124, default 1953124): Created a new partition 1 of type 'Linux' and of size 100 MiB. Command (m for help): Selected partition 1 Partition type (type L to list all types): Changed type of partition 'Linux' to 'W95 FAT32 (LBA)'. Command (m for help): Partition type p primary (1 primary, 0 extended, 3 free) e extended (container for logical partitions) Select (default p): Using default response p. Partition number (2-4, default 2): First sector (206848-1953124, default 206848): Last sector, +sectors or +size{K,M,G,T,P} (206848-1953124, default 1953124): Created a new partition 2 of type 'Linux' and of size 852.7 MiB. Command (m for help): The partition table has been altered. Syncing disks.

パーティションを確認する。

$ fdisk -l ArchLinuxARM_20160202.img

パーティションが作成されていることを確認する。ここの数値は後で使用する(場合もある。詳しく後述)。

Disk ArchLinuxARM_20160202.img: 953.7 MiB, 1000000000 bytes, 1953125 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x1fd6017a Device Boot Start End Sectors Size Id Type ArchLinuxARM_20160202.img1 2048 206847 204800 100M c W95 FAT32 (LBA) ArchLinuxARM_20160202.img2 206848 1953124 1746277 852.7M 83 Linux

Sector 表示ではなく Byte 表示にする場合は numfmtを通してあげればよい。

$ fdisk -l ArchLinuxARM_20160202.img | numfmt --header=8--field=2-4--from-unit=512
Disk ArchLinuxARM_20160202.img: 953.7 MiB, 1000000000 bytes, 1953125 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x6d37494e Device Boot Start End Sectors Size Id Type ArchLinuxARM_20160202.img1 1048576 105905664 104857600 100M c W95 FAT32 (LBA) ArchLinuxARM_20160202.img2 105906176 999999488 894093824 852.7M 83 Linux

メモ:パーティションテーブルはテキストファイルとして残しておくことができる。

$ sfdisk -d ArchLinuxARM_20160202.img >ArchLinuxARM_20160202.dump
$ cat ArchLinuxARM_20160202.dump
label: dos label-id: 0xd382ffcd device: ArchLinuxARM_20160202.img unit: sectors ArchLinuxARM_20160202.img1 : start= 2048, size= 204800, type=c ArchLinuxARM_20160202.img2 : start= 206848, size= 1746277, type=83

ファイルシステムの作成(フォーマット)

mkfs.vfatがなければ dosfstoolsをインストールしておく。

# pacman -S dosfstools

ループデバイスへのマウント

さて、fdiskでイメージファイルにパーティションを作成したが、複数パーティションの場合は losetupを使ってイメージファイルのパーティションをループデバイスとして扱えるようにする。

losetupは OS によってオプションが異なるらしいので必ず実行環境で man を参照した方がよい

Arch Linux ARM 上の losetupはイメージファイル内容のパーティションを自動的に認識してくれる(-P, --partscanオプションで強制も可能)。

# losetup -f --show ArchLinuxARM_20160202.img
/dev/loop0
# losetup -l
NAME       SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE
/dev/loop0         0      0         0  0 /home/alarm/ArchLinuxARM_20160202.img
# lsblk /dev/loop0
NAME      MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
loop0       7:0    0 953.7M  0 loop 
├─loop0p1 259:0    0   100M  0 loop 
└─loop0p2 259:1    0 852.7M  0 loop 

Ubuntuの場合(w kpartx)

Ubuntuでも kpartxを使うと Arch Linuxlosetupのように、パーティションを自動で認識してくれる。

$ sudo apt-get install kpartx
$ sudo kpartx -av ArchLinuxARM_20160202.img
$ lsblk /dev/loop0
add map loop0p1 (252:0): 0 204800 linear /dev/loop0 2048 add map loop0p2 (252:1): 0 1746277 linear /dev/loop0 206848 NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT loop0 7:0 0 953.7M 0 loop ├─loop0p1 (dm-0) 252:0 0 100M 0 part └─loop0p2 (dm-1) 252:1 0 852.7M 0 part

kpartxはループデバイスを /dev/mapper以下に配置する。

Ubuntuの場合(w/o kpartx)

kpartxを使わない場合、ちょっと複雑になる。例えば、Ubuntulosetupパーティションを認識してくれない。(fdisk /dev/loopXとすればテーブルは表示はできる)

$ sudo losetup -f ArchLinuxARM_20160202.img
/dev/loop0
$ lsblk /dev/loop0
NAME  MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
loop0   7:0    0 953.7M  0 loop

この場合は losetupするときに --offset--sizelimitで範囲を指定する。パーティションのサイズは sfdisk -lでユニットをセクタに指定する。

$ sfdisk -l -u S ArchLinuxARM_20160202.img 2>/dev/null | tail -n 4
ArchLinuxARM_20160202.img1 2048 206847 204800 c W95 FAT32 (LBA) ArchLinuxARM_20160202.img2 206848 1953124 1746277 83 Linux ArchLinuxARM_20160202.img3 0 - 0 0 Empty ArchLinuxARM_20160202.img4 0 - 0 0 Empty

上記の開始位置とセクタ数を losetupで指定する。1 セクタは 512 byte。

$ sudo losetup -f --offset $((512*2048)) --sizelimit $((512*204800)) ArchLinuxARM_20160202.img
$ sudo losetup -f --offset $((512*206848)) --sizelimit $((512*1746277)) ArchLinuxARM_20160202.img
$ sudo losetup -a
$ lsblk /dev/loop0 /dev/loop1
/dev/loop0: [0801]:552769 (/home/alarm/ArchLinuxARM_20160202.img), offset 1048576, sizelimit 104857600 /dev/loop1: [0801]:552769 (/home/alarm/ArchLinuxARM_20160202.img), offset 105906176, sizelimit 894093824 NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT loop0 7:0 0 100M 0 loop loop1 7:1 0 852.7M 0 loop

開始セクタとセクタ数のバイト変換は numfmt --from-unit 512などを組み合わせて調べることもできる。

$ sfdisk -l -u S ArchLinuxARM_20160202.img 2>/dev/null | tail -n 4 | awk '{ print $1, $2, $4 }' | numfmt --field 2 --from-unit 512 | numfmt --field 3 --from-unit 512
ArchLinuxARM_20160202.img1 1048576 104857600 ArchLinuxARM_20160202.img2 105906176 894093824 ArchLinuxARM_20160202.img3 0 0 ArchLinuxARM_20160202.img4 0 0

ファイルシステムの作成

ファイルシステムの作成は /dev/sda1などと同じように /dev/loopXに対して実行する。

# mkfs.vfat /dev/loop0p1
# mkfs.ext4 /dev/loop0p2

あとは通常の microSD の作成と同じように進める。

$ mkdir root
$ sudo mount /dev/loop0p2
$ sudo mkdir root/boot
$ sudo mount /dev/loop0p1 root/boot
$ sudo bsdtar -xpf ArchLinuxARM-rpi-latest.tar.gz -C root
$ sudo umount /dev/loop0p1 /dev/loop0p2
$ sudo losetup -d /dev/loop0

出来上がった img を ZIP で圧縮すれば 270MB くらいまで小さくなるのでそのまま置いておいてもそれほど容量は使わない。


Raspberry Pi 1 Model B+ 上でディスクイメージを作成するためのスクリプト

x86_64 Ubuntu で Arch Linux ARM を動かしてみる

$
0
0

先日、Arch Linux ARM のディスクイメージ作った。

mattintosh.hatenablog.com

今回はこのディスクイメージと QEMUを使って Ubuntuで Arch Linux ARM のエミュレーションをやってみたのでそのメモ。


前回作ったディスクイメージをコピー。名前が長いと面倒なので qemu-alarm.imgとした。

cp ArchLinuxARM_20160202.img qemu-alarm.img

カーネルGitHubで頒布してくれていた人のを借りてきた。

そのままだと /dev/mmcblk0p1というか /dev/sda1がマウント出来ず、起動する度にエラーになるのでこれを一度無効にする。

qemu-system-arm -kernel kernel-qemu-4.1.bin -M versatilepb -cpu arm1176 -m256"root=/dev/sda2 rw panic=1 init=/bin/bash"-hda qemu-alarm.img

vi/etc/fstab/dev/mmcblk0p1行をコメントアウトする。

vi /etc/fstab

exitしてもう一度 QEMUを起動する。この時に init=/bin/bashはつけない。

qemu-system-arm -kernel kernel-qemu-4.1.bin -M versatilepb -cpu arm1176 -m256-serial stdio -append"root=/dev/sda2 rw panic=1 console=ttyAMA0,115200"-hda qemu-alarm.img -net nic -netuser,net=192.168.1.0/24,hostfwd=tcp::12345-:22

いつもはこういうことには関心するけどこれはなんか気持ち悪い…w

f:id:mattintosh4:20160207213341p:plain

さて、ディスクイメージは 1 GB で作ったのでちょっと拡張する。ディスクイメージの拡張は truncateqemu-image resizeでできる。どちらも +を付けたりすることで「追加」になるようだ。

truncate -s+3GB alarm.img
qemu-image resize alarm.img +`numfmt --from si 3G`

再び QEMUを起動してディスクサイズを確認する。ファイルシステムはまだ拡張していない状態。

f:id:mattintosh4:20160207214051p:plain

パーティションテーブルを編集して /dev/sda2を作り直す。

fdisk /dev/sda

f:id:mattintosh4:20160207214254p:plain

再起動後、ファイルシステムを拡張する。

resize2fs /dev/sda2

QEMUの制限でメモリが 256 MB しかないのでスワップファイルを作成する。

dd if=/dev/zero of=/swapfile bs=1M count=256
mkswap /swapfile
chmod0600 /swapfile
swapon /swapfile
echo /swapfile none swap swap 0 0 >>/etc/fstab

/dev/sda1/dev/mmcblk0)を読み込むための方法として udev に新しいルールを作るものがあるらしい。

vi /etc/udev/rules.d/90-qemu.rules
KERNEL=="sda"SYMLINK+="mmcblk0"KERNEL=="sda?"SYMLINK+="mmcblk0p%n"KERNEL=="sda2"SYMLINK+="mmcblk0p2"

そうすると起動するときに /dev/mmcblk => /dev/sdaみたいなリンクができる。

と、してみたがやっぱり /bootにマウントしてくれないんだよな…。/etc/fstab/dev/sda1って書いてもダメだし。

起動後にマウントはできるから起動順とかの問題かね。

microSD に入っている Arch Linux ARM を扱う方法もあるみたいだし、Raspberry Pi 本体での作業にはそれほど拘らなくてもいいのかも。

microSD に入っている Arch Linux ARM を QEMUで起動する

Arch Linux ARM を焼いてある microSD が転がっていたのでカードリーダーに突っ込んで QEMUで起動できるのか試してみた。デバイスは /dev/sdc

そのままだと /dev/sdcに書き込み権限が無いので適当にパーミッションを変更。VirtualBoxの rawdisk イメージと同じようなものか。

chmod0666 /dev/sdc

-drive file=/dev/sdc,if=scsi/dev/sdcを読みに行くようにして起動。

qemu-system-arm -kernel kernel-qemu-4.1.7.bin -M versatilepb -cpu arm1176 -m256-append"root=/dev/sda2 rw"-drivefile=/dev/sdc,if=scsi

あっさり出来てしまうから困る。

f:id:mattintosh4:20160207221941p:plain


うーん、ということは Raspberry Pi の勉強会は実機がなくてもなんとかなるところはなんとかなるかもなぁ…。ネットワークがちょっと難だけど。

それより udev をもうちょっと勉強しなきゃだめかな。

FileSystemObject さんが遅い

$
0
0

前に VBAで FileSystemObject を使った再帰的なファイル検索をした気がするけど、当時の記憶でネットワークドライブに対してファイル検索を行うコードを書いたら超絶遅い。マジで「こんなん使ってられませんわ!」レベル。

ふと、思い出して Dir関数使ってみたらめちゃめちゃ早い。どれくらい早いかっていうと5分かかるものが10秒で終わるレベル。FileSystemObject は .SubFoldersメソッド.Filesメソッドも遅い。

とりあえず Collection の先頭に起点となるフォルダを突っ込んで、そこから全サブフォルダを再起検索。それからサブフォルダをループで回してファイル検索。コマンドプロンプトだと dir /s /a-dだけで出来るんだけどなぁ…。

OptionExplicitSub macro()Dim dirstack AsNew Collection
    dirstack.Add"C:\Windows"Dim i AsLong
    i =1Dim strName AsStringDo
        strName =Dir(dirstack(i)&"\",vbDirectory)DoWhile strName <>""If(GetAttr(dirstack(i)&"\"& strName)AndvbDirectory)=vbDirectory _And strName <>"." _And strName <>".." _Then
                dirstack.Add dirstack(i)&"\"& strName
            EndIf
            strName =Dir()Loop
        i = i +1If i > dirstack.CountThenExitDoEndIfLoop
    
    i = i +1Dim f asVariantForEach f in dirstack
        strName =Dir(f &"\"&"*.log")DoWhile strName <>""
            Cells(i,1)= f &"\"& strName
            strName =Dir()
            i = i +1LoopNext f
    
    Columns.Sort _
        Key1:=Columns(1), _
        Order1:=xlAscending, _
        Header:=xlGuess, _
        MatchCase:=False, _
        Orientation:=xlTopToBottom
    
    Columns.AutoFit
    
EndSub

Dir関数はファイル名順に処理してくれないのが欠点だけど .Sortメソッドがそこそこ速いのでこれはなんとかなりそう。

Raspberry Pi 3がやってきたので艦これの動作検証をしてみた

$
0
0

発売後、しばらく入荷未定だった Raspberry Pi 3 が秋葉原のマルツで販売していたので買ってきた。現在販売されているのは element14 版のみで、RS 版は入荷未定(予約受付中)。

とりあえず Raspberry Pi 1B+/2B/3B を並べて撮ってみる。RPi3 になっても見た目はあまり変わらないが、LED の場所が変更されている。microSD のソケットはバネ無しのタイプに変更されたらしい。(フラットケーブルのストッパーは RS 版が白、element14 版が黒?)

f:id:mattintosh4:20160410183901j:plain

RPi2 で使っていた OS は RPi3 でもそのまま使えるので早速 microSD を移して起動。RPi3 から消費電力が増えているが、1 A の電源でも起動はできるらしい(Bluetoothを使う場合は足りないかも)。今回から新たに追加された無線 LAN も試してみたが、感度は超小型タイプの USB アダプタと同じくらいだった。

数値的なベンチマークは既に他のサイトにも出ているので、いつものように“艦これ”で(体感)ベンチマーク。スペックを見た限りではあまりパワーアップしていないように感じたが、実際に動かしてみるとパワーアップしているのがよくわかる。以前はもたつきが目立った航空戦もスムーズに動く。しかも前回のようなデスクトップ環境なしで動かしていたときとは異なり、今回は Ubuntuで MATE を起動している状態にもかかわらずこの動きである。

ちなみに RPi2 のときはこんな感じ。(このときは画面キャプチャの負荷を減らすために Xnest でデスクトップ PC に出力した)

RPi1 の頃は重すぎて GUIは勧められず、RPi2 になってある程度の設定が出来る人には GUIを勧めていたが、RPi3 は初心者にも GUIを勧められそうだと感じた。値段も RPi2 に無線 LAN や Bluetoothアダプタを買うよりも RPi3 単体の方が安い。

RPi3 の在庫が無くて RPi2 で妥協するよりは少し我慢して RPi3 を買ったほうがいいと思います(b´∀`)ネッ!

RS 版と element14 版 Raspberry Pi 3 が揃ったので並べてみた

$
0
0

入荷待ちだった RS 版 Raspberry Pi が今週金曜日から安定供給されるようになった(?)ようなので買ってきた。

秋月電子、マルツの両方で販売されていて、価格はどちらも税込みで6,200円。KSY だと Raspberry Pi 3 は送料無料対象の価格帯なので税込み5,670円で購入できる。

「中身は同じ」と言われている RS 版と element14 版だけど、フラットケーブルの留め具の色が違ったり微妙な違いはある。

  • RS 版:留め具は白。「Made in the UK」の刻印。
  • element14 版:留め具は黒。「Made in PRC」の刻印。

左が RS 版、右が element14 版。

f:id:mattintosh4:20160424143424j:plain

ハンダ付けは中国製の element14 版の方が若干綺麗。この辺は中国に分があるのだろうか。

f:id:mattintosh4:20160424143427j:plain

とりあえずサーバ用として使っている RPi2 を取り替えて1ヶ月様子見かなぁ。RPi3 にしたからといって電気代が極端に増えるってことはないだろうけど…。

Raspberry PiのChromiumが復活

なんかのメモ

$
0
0
BEGIN {
    ORS = "\t"print ID
}
/keyword_0/ {
    flg[0] = 1
    str[0] = $0
}
/keyword_1/ {
    flg[1] = 1
    str[1] = $0
}
END {
    for (i = 0; i <= 1; i++) {
        if (flg[i] != 1) {
            str[i] = "null"
        }
        print str[i]
    }
    ORS = "\n"print""
}

CentOS 7×Oracle Database 11g XE×Ubuntu

$
0
0

VirtualBoxCentOS 7 Minimal をインストールして Oracle 11g XE(Express Edition)をインストールしたときのメモ。

VirtualBoxの設定は Red Hat (64-bit) でほぼデフォルト、ネットワークのみブリッジに変更。

いきなりネットワークが使えなかったのでまずはネットワーク。(インストール時に設定をしておけばいいようである)

# ip addr add 192.168.1.100/24 dev enp0s3
# ip route add default via 192.168.1.1
# echo nameserver 8.8.8.8 >>/etc/resolv.conf
# echo nameserver 8.8.4.4 >>/etc/resolv.conf

インストール時に固定 IP で設定した場合の /etc/sysconfig/network-scripts/ifcfg-enp0s3は以下の状態。(インストール時に設定しておくと二重引用符が付くのは何故だ…)

TYPE="Ethernet"
BOOTPROTO="none"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
NAME="enp0s3"
UUID="f0c2c328-ea1a-420c-9bc0-b872553ca1b8"
ONBOOT="yes"
HWADDR="08:00:27:DA:FD:20"
IPADDR0="192.168.1.100"
PREFIX0="24"
GATEWAY0="192.168.1.1"
DNS1="8.8.8.8"
DNS2="8.8.4.4"
IPV6_PEERDNS="yes"
IPV6_PEERROUTES="yes"

システムのアップデート。

# yum update
# reboot

Oracle 11g XE のインストールに bc、 libaio が必要。unzip はインストーラの展開用。net-tools は /etc/init.d/oracle-xe configureするときに netstatが無いというメッセージが出るので(特に無くてもかまわないとは思うが)。

# yum -y install bc libaio net-tools unzip

Oracle 11g XE のインストールには 980 MB のスワップが必要だが、CentOSのインストール時に 800 MB 程度に設定されていたようなのでスワップを追加。(インストール時に 1024 としておけばインストール可能だった)

# dd if=/dev/zero of=/swapfile bs=1M count=1000
# chmod 0600 /swapfile
# mkswap /swapfile
# swapon /swapfile
# echo /swapfile swap swap defaults 0 0 >>/etc/fstab

Oracle 11g XE のインストール。

# unzip oracle-xe-11.2.0-1.0.x86_64.rpm.zip
# rpm -ivh Disk1/oracle-xe-11.2.0-1.0.x86_64.rpm
# /etc/init.d/oracle-xe configure

oracle_env.shの読み込みと ~/.bashrcへの設定。

$ . /u01/app/oracle/product/11.2.0/xe/bin/oracle_env.sh
$ echo . /u01/app/oracle/product/11.2.0/xe/bin/oracle_env.sh >>~/.bashrc

クライアント側の Ubuntuに sqlplus をインストールするには alienを使って RPMパッケージをインストールする方法があるようだが、Debian系に RPMはちょっとねぇ…ってことでパッケージシステムには入れないように進める。

instantclient の basic と sqlplus をダウンロードして解凍。aliasLD_LIBRARY_PATHを設定するようにして sqlplusを使用可能にしておく。

$ unzip instantclient-basic-linux.x64-12.1.0.2.0.zip
$ unzip instantclient-sqlplus-linux.x64-12.1.0.2.0.zip
$ alias sqlplus="LD_LIBRARY_PATH=~/instantclient_12_1 ~/instantclient_12_1/sqlplus"
$ alias sqlplus >>~/.bashrc

さて、接続…

$ sqlplus system/password@192.168.1.100

としたが、エラーが返ってきた。なんか接続できてないっぽい。

ERROR: ORA-12543: TNS:destination host unreachable

ファイヤーウォールかなぁと思って iptablesみたけど何も書いてない。ググるCentOS 7 は firewall-cmdっていうので色々やってるらしい。へぇ。

1521 番ポートを解放しておく。

# firewall-cmd --zone=public --add-port=1521/tcp --permanent
# firewall-cmd --reload
# firewall-cmd --list-all

さて遊ぼう。

🍎 Nihonshu アップデート情報 2016年8月4日 🍷

$
0
0

久しぶりの更新です。最近、Macもすっかり使わなくなってしまいました。

WINE 1.9.7 から何故か ranlib の処理で弾かれてしまいビルドに時間を費やすこと数日…。configure 時にトリプルを i686-apple-darwin13 でセットしていたのが問題だったようで…。とりあえず WINE 1.9.15 版できました。(暫く放置していたうちに色々変わったらしいけどまだ何が変わったのか調べてません…)

今回から EasyWine.app にだけ、DirectX9 38〜43、X3DAudio を同梱しました。起動時にバイナリ比較結果で自動配置するようにしてあるので特に何かする必要は無いです(システムドライブにライブラリが存在する場合、そちらを勝手に使うので厳密なオーバライド設定はしてません)。EasyWine.app/Contents/Resources/wine/lib/wine/nativedlls内に配置されている *.dll を自動的にロードするので追加したい場合はそちらにネイティブライブラリを置いておくといいかもしれません。ただし、quartz.dll などは regsvr32 を通す必要があります。

DirectX9 43 を使うゲームで知ってるのが『東方心綺楼』くらいなのですが、体験版で起動テストをしてみましたが特に問題ない様子。

そう言えば去年の冬コミのカタログ ROM 版の売り残りを買うと言っておいて結局買ってなかったり…。今年の夏コミもまだカタログ買ってないのですが Web 版とかもあるからわざわざ Macでカタログ見る必要ないんじゃないかな、とかなんとか。

次はまた冬コミの時期じゃないかな\(^o^)/

Maker Faire Tokyo 2016 に行ってきた

$
0
0

2016年8月6日、7日に東京ビッグサイトで行われた『Maker Faire Tokyo 2016』に行ってきました。(仕事前だったので7日の終了間際だけなんだけど…)

MFTにやってきました

Makoto Yoshidaさん(@mattintosh4)が投稿した写真 -

目当ては『アールエスコンポーネンツ株式会社』さん(F01-09)、『Raspberry Pi Shop by KSY』さん(F01-10)、『株式会社スイッチサイエンス』さん(F02-10)だったんだけど、まずは目玉展示品『1/2 タチコマ』。いただいたパンフレットによると2018年3月に社会実装実証を予定しているとのこと。

1/2タチコマ☆*:.。. o(≧▽≦)o .。.:*☆ #MFT2016

Makoto Yoshidaさん(@mattintosh4)が投稿した写真 -

アールエスコンポーネンツさんのところでアンケートに答えて Raspberry Piのクリアファイルをもらいつつ隣の KSY さんのところへ。目当ての Raspberry Pi用アルミケース『Pi ケース Leg V1』のサンプル見せてもらってファン対応モデルを1個購入(¥2,500)。注意事項として、今回のサンプルには RPi3 のワイヤレスモジュール用のスリットが入っていないらしく、電波が弱くなるかもしれないとのこと。

筐体の作りは非常によく、Raspberry Piをがっちり守ってくれそう。これはファンが取り付け可能なタイプの方なんだけど、吸気できても排気が難しい構造なような(?)。

ただ、無線モジュールのスリット問題以前に、電源用 microUSB ケーブル部分の穴が小さく、コネクターがひっかかって挿さらないといった問題があった…。自分が使ってるのは Anker 製のケーブルで、ケースの穴より一回り大きい。ほかにもいくつかケーブルは持っていたけどいずれもコネクター部分がひっかかってしまい、使えなかった。

秋葉原あたりで探せばもう少しコネクターの小さなケーブルもあるだろうけど、2.4 A 対応タイプとかでそれがあるのかどうかはわからない。ケースの素材がアルミだから自分で削ってもいいのだけど。

スイッチサイエンスのブースを見てきたけど、ヤバイArduino欲しくなる、Edison 欲しい!。IoT(Internet of Toilet)も面白かったな。アイディア次第で色々遊べそう。

次回はもうちょっと長く滞在したいなぁ、と思ったのでした。

Audio CD を RAW データで取り込む

$
0
0

この前買った CD をいい加減取り込まなくてはと思いつつ、あきばおーでポータブル DVD ドライブを買ってきた。最近だと ¥2,500 もあれば買えてしまうのね。1台買っておけばよかった。(でも読み込み 24x って遅い…)

取込みはいつも cdparanoia を使って、NeroAacEnc でエンコードしているのだけど、今日は RAW でも取り込んで遊んでみた。ちなみに Audio CD は dd コマンドでは取込みが出来ない。

Audio CD を RAW データで取り込む

まずは cdrdao の使い方を見てみよう。

cdrdao

cdrdao は cdrdaoだけでは動作せず、cdrdao <command>形式で実行する必要がある。

Cdrdao version 1.2.3 - (C) Andreas Mueller Usage: cdrdao [options] [toc-file] command: show-toc - prints out toc and exits toc-info - prints out short toc-file summary toc-size - prints total number of blocks for toc read-toc - create toc file from audio CD read-cd - create toc and rip audio data from CD read-cddb - contact CDDB server and add data as CD-TEXT to toc-file show-data - prints out audio data and exits read-test - reads all audio files and exits disk-info - shows information about inserted medium discid - prints out CDDB information msinfo - shows multi session info, output is suited for scripts drive-info - shows drive information unlock - unlock drive after failed writing blank - blank a CD-RW scanbus - scan for devices simulate - shortcut for 'write --simulate' write - writes CD copy - copies CD Try 'cdrdao -h' to get a list of available options

今回は読み取りを行うので read-cdコマンドを使う。これもヘルプを見てみる。

cdrdao read-cd
Cdrdao version 1.2.3 - (C) Andreas Mueller Usage: cdrdao read-cd [options] toc-file options: --device [proto:]{|device} - sets SCSI device of CD-ROM reader --driver - force usage of specified driver for source device --datafile - name of data file placed in toc-file --session # - select session --fast-toc - do not extract pre-gaps and index marks --read-raw - read raw data sectors (including L-EC data) --no-mode2-mixed - don't switch to mode2_mixed --rspeed - selects reading speed --read-subchan - defines sub-channel reading mode = rw | rw_raw --tao-source - indicate that source CD was written in TAO mode --tao-source-adjust # - # of link blocks for TAO source CDs (def. 2) --paranoia-mode # - DAE paranoia mode (0..3) --with-cddb - retrieve CDDB CD-TEXT data while copying --cddb-servers - sets space separated list of CDDB servers --cddb-timeout # - timeout in seconds for CDDB server communication --cddb-directory - path to local CDDB directory where fetched CDDB records will be stored --force - force execution of operation -v # - sets verbose level

今回はデータファイルを作成するので --datafileオプションを使う。今回は --swapを使って s16le -> s16be にバイトオーダーを入れ替えてみる。(※こんな話をしておきながら実は --swapを使わずに dd conv=swabした方が何かと都合がよい)

CD はこれ。(その情報は重要か?)

Walkure Attack!(初回限定盤)(DVD付)

Walkure Attack!(初回限定盤)(DVD付)

※面倒なので以降、シェルのブレース展開を使う。

cdrdao read-cd--rspeed24--read-raw--swap--datafile'Walküre_Attack!'.{bin,toc}

TOC ファイルは以下のようなものになる。CATALOG は値を調べてみたら JAN が入ってるっぽい。ISRC(International Standard Recording Code)とは日本語で「国際標準レコーディングコード」のこと。

CD_DA CATALOG "4580325321982" // Track 1 TRACK AUDIO NO COPY NO PRE_EMPHASIS TWO_CHANNEL_AUDIO FILE "Walküre_Attack!.bin" 0 04:54:47 // Track 2 TRACK AUDIO NO COPY NO PRE_EMPHASIS TWO_CHANNEL_AUDIO FILE "Walküre_Attack!.bin" 04:54:47 04:12:55 // Track 3 TRACK AUDIO NO COPY NO PRE_EMPHASIS TWO_CHANNEL_AUDIO FILE "Walküre_Attack!.bin" 09:07:27 03:54:70 // Track 4 TRACK AUDIO NO COPY NO PRE_EMPHASIS TWO_CHANNEL_AUDIO FILE "Walküre_Attack!.bin" 13:02:22 04:04:28 // Track 5 TRACK AUDIO NO COPY NO PRE_EMPHASIS TWO_CHANNEL_AUDIO FILE "Walküre_Attack!.bin" 17:06:50 04:25:60 // Track 6 TRACK AUDIO NO COPY NO PRE_EMPHASIS TWO_CHANNEL_AUDIO FILE "Walküre_Attack!.bin" 21:32:35 04:30:72 // Track 7 TRACK AUDIO NO COPY NO PRE_EMPHASIS TWO_CHANNEL_AUDIO FILE "Walküre_Attack!.bin" 26:03:32 05:34:68 // Track 8 TRACK AUDIO NO COPY NO PRE_EMPHASIS TWO_CHANNEL_AUDIO FILE "Walküre_Attack!.bin" 31:38:25 05:14:57 // Track 9 TRACK AUDIO NO COPY NO PRE_EMPHASIS TWO_CHANNEL_AUDIO FILE "Walküre_Attack!.bin" 36:53:07 05:11:25 // Track 10 TRACK AUDIO NO COPY NO PRE_EMPHASIS TWO_CHANNEL_AUDIO FILE "Walküre_Attack!.bin" 42:04:32 04:26:38 // Track 11 TRACK AUDIO NO COPY NO PRE_EMPHASIS TWO_CHANNEL_AUDIO FILE "Walküre_Attack!.bin" 46:30:70 04:39:52 // Track 12 TRACK AUDIO NO COPY NO PRE_EMPHASIS TWO_CHANNEL_AUDIO ISRC "JPVI01610890" FILE "Walküre_Attack!.bin" 51:10:47 05:09:18

RAW データの再生

出来上がった RAW データは mplayer で再生できる。

mplayer --demuxer rawaudio 'Walküre_Attack!'.bin

ffmpeg(ffplay)の場合はフォーマット、レート、チャンネルを指定しないと正しく再生できない。(cdrdao read-cd --swapしていない場合は -f s16le

ffplay -f s16be -ar44100-ac2-i'Walküre_Attack!'.bin

VLC の場合はチャンネル数のデフォルトが 2なので --rawaud-channels=2は省略してもよい。(cdrdao read-cd --swapしていない場合は --rawaud=fourcc=s16l

vlc 'Walküre_Attack!'.bin --demux=rawaud--rawaud-fourcc=s16b--rawaud-samplerate=44100

dd conv=swabしている場合は s16le になる。

dd if='Walküre_Attack!'.bin of='Walküre_Attack!'.bin.swaped conv=swab
mplayer --demuxer rawaudio 'Walküre_Attack!'.bin.swaped
ffplay -f s16le -ac2'Walküre_Attack!'.bin.swaped
vlc 'Walküre_Attack!'.bin --demux=rawaud--rawaud-samplerate=44100

dd で変換した場合、TOC 内に記述されているファイル名と一致しなくなるので古い方を捨ててリネームしておく。

rm'Walküre_Attack!'.bin
mv'Walküre_Attack!'.bin.swaped 'Walküre_Attack!'.bin

RAW データの分割

TOC ファイルから CUE シートを作成する。

toc2cue 'Walküre_Attack!'.{toc,cue}

bchunk を使って分割、WAVE ファイルを作成する。(-wをつけない場合は BIN 状態のまま分割される)

bchunk -w'Walküre_Attack!'.{bin,cue,}

自動化

RAW 読み込み、スワップ、CUE シート作成、WAV ファイル作成まで一括で。デバイスの指定とか環境によっては細かい指定が必要かも。

#!/bin/shset-eset-x:${1:?}

cdrdao read-cd--read-raw--datafile"$1".bin "$1".toc
mv"$1".bin "$1".bin.orig
dd conv=swab if="$1".bin.orig of="$1".bin
rm"$1".bin.orig
toc2cue "$1".toc "$1".cue
bchunk -w"$1".bin "$1".cue "$1 - "

参考

forums.freebsd.org

linux.die.net

SOX で Upsampling? stdout with mpv とか

$
0
0

この前、Raspberry Piで cdrdao と toc2cue、bchunk でオーディオの取り込みが出来るようにした。

mattintosh.hatenablog.com

AACへのエンコードは長い間 Nero AAC Codec を使ってたが、結構古いしそろそろ最近のエンコーダの方がいいかなと思い、変えてみることにした。

最近よく「ハイレゾ」って聞くけど色々放浪してたら、SoXでサンプリングレートを弄ったりする遊びがあるらしい。(Windowsでは foober2000 のプラグインに入ってるっぽい?)

http://www.hcn.zaq.ne.jp/___/unix/sox-ja.html#E-rateにある最高品質再サンプルを参考に 44.1kHz s16le を 96kHz f32le に変換。

sox -G infile.wav outfile.wav rate -v-I-b9096000 dither -S

ファイルサイズがトンデモナイことになる。これは流石に困るので、mpv で AACに変換する。Libavcodecだから FFmpegとかと同じかね。FFmpegAACを使うときに -strict experimentalの指定が面倒くさい。

soxから標準出力(stdout)を行う場合はタイプを指定する必要がある。標準出力ファイル名は -。(-t f32でもいいのか? Precision が 32-bit にならない?)

sox -G infile -e floating-point -b32-t raw - rate -v-I-b9096000 dither -S

mpv 側の標準入力で受け取る場合も -でもいいが、明示的にファイルディスクリプタを指定できる fd://012書式があるのでそちらを使う。RAW で送られてくるのでソースのフォーマットなどを指定する必要がある。オプションの書き方が FFmpegともまた違って面白い。--oac=aacを指定するとバージョンによっては Experimental Codec の注意書きが出るようだ(Arch Linux ARM の mpv では出ないが、Ubuntuの 16.04 の mpv では出る)。

mpv --no-config--demuxer=rawaudio--demuxer-rawaudio-channels=2--demuxer-rawaudio-format=floatle--demuxer-rawaudio-rate=96000 fd://0--oac=aac--oacopts=ab=192k

SoXではスペクトログラムも作成出来るのでやってみる。

sox infile.wav -n spectrogram -h
Input File : '干物妹!うまるちゃん - UMARU THE BEST - 01.wav' Channels : 2 Sample Rate : 44100 Precision : 16-bit Duration : 00:03:32.01 = 9349788 samples = 15901 CDDA sectors File Size : 37.4M Bit Rate : 1.41M Sample Encoding: 16-bit Signed Integer PCM

f:id:mattintosh4:20160824001803p:plain

Input File : '干物妹!うまるちゃん - UMARU THE BEST - 01 (96kHz).wav' Channels : 2 Sample Rate : 96000 Precision : 24-bit Duration : 00:03:32.01 = 20353280 samples ~ 15901 CDDA sectors File Size : 163M Bit Rate : 6.14M Sample Encoding: 32-bit Floating Point PCM

f:id:mattintosh4:20160824001817p:plain

ぱっと見、44.1kHz の方は 22.05kHz をぶっちぎってるような…。

では AACに変換したものから PCM に書き戻してスペクトログラムを見てみる。mpv はオプション調べるのがめんどくさかったのでとりあえず ffmpegを使う。

ffmpeg -i infile-96kHz.m4a -f f32le hoge.f32le
sox -b32-c2-r96000-t f32 hoge.f32le -n spectrogram -h

f:id:mattintosh4:20160824010652p:plain

なんか所々ぴょんぴょんしたものもある。これはそこそこまともに戻ってる方なんだろうか。


今回から mpv でエンコードしてみたけど、音質は AACにしては頑張ってる方なんじゃないだろうか。(iPhoneで聴く限りは)

とりあえず一括変換用のスクリプト書いてみた。設定はまた暇なときだなぁ。仕事あがりで聴き比べようとしても疲れてもう無理だ…。

#!/bin/shset-eset-x:${1:?}

which sox mpv

for f
docase${f}in
    *.wav|*.WAV);;
    *)continue;;esac
    
    sox -G"${f}"-e floating-point -b32-t raw - rate -v-I-b9096000 dither -S \
    | mpv --no-config--demuxer=rawaudio \
                      --demuxer-rawaudio-channels=2 \
                      --demuxer-rawaudio-format=floatle \
                      --demuxer-rawaudio-rate=96000 \
                      fd://0 \
                      -o"${f%.*}".m4a --oac=aac--oacopts=ab=192kdone

追記(2016年8月24日)

SoXのオプションを少し読んだのでちょい修正。

書式が少し特殊である。

sox [gopts][[fopts] infile]... [fopts] outfile [effect [effopt]]...

ショートオプションだとわかりづらいのでロングオプションを使用。

今回のサンプルは bchunkcdrとして書き出したので --endianも指定する。自分の場合、cdrdaoのあと、dd conv=swabをかけているので littleだが場合によっては bigかもしれない。

sox -V3--buffer65536\--guard\--multi-threaded\--show-progress\--type cdr \--endian little \
        CROW\'SCLAW\ -\ Shelling\ And\ Torpedoing\ -\ 02.cdr \--bits24\--type raw - \
        rate -v-I96000\
        dither -S\
| mpv --no-config\--demuxer{=rawaudio,-rawaudio-{channels=2,format=s24le,rate=96000}}\
      fd://0\-o outfile.m4a \--oac=aac\--oacopts=ab=192k
sox: SoX v14.4.2 sox INFO formats: `CROW'SCLAW - Shelling And Torpedoing - 02.cdr': overriding file-type byte-order Input File : 'CROW'SCLAW - Shelling And Torpedoing - 02.cdr' Channels : 2 Sample Rate : 44100 Precision : 16-bit Duration : 00:03:10.65 = 8407812 samples = 14299 CDDA sectors File Size : 33.6M Bit Rate : 1.41M Sample Encoding: 16-bit Signed Integer PCM Endian Type : little Reverse Nibbles: no Reverse Bits : no Output File : '-' (raw) Channels : 2 Sample Rate : 96000 Precision : 24-bit Duration : 00:03:10.65 = 18302720 samples ~ 14299 CDDA sectors Sample Encoding: 24-bit Signed Integer PCM Endian Type : little Reverse Nibbles: no Reverse Bits : no Comment : 'Processed by SoX'sox INFO sox: effects chain: input 44100Hz 2 channels sox INFO sox: effects chain: gain 44100Hz 2 channels sox INFO sox: effects chain: rate 96000Hz 2 channels sox INFO sox: effects chain: gain 96000Hz 2 channels sox INFO sox: effects chain: dither 96000Hz 2 channels sox INFO sox: effects chain: output 96000Hz 2 channels
Viewing all 878 articles
Browse latest View live