NetBSD上のmplayerで、audioデバイスとvideoデバイスを指定して表示させる

この記事は、NetBSD Advent Calendar 2025の14日目の記事です。

はじめに

mplayerで出力するオーディオデバイスを指定する方法は、pkgsrc/multimedia/mplayerをpulseaudioオプションを有効にして使っている私には有用です。 OSSしか使っていない場合にも、HDMIコネクターの内蔵されたマシンを利用している場合には、内蔵スピーカーとHDMI出力を切り替える必要があると思いますので、 有用かもしれません。

一方で、webcamの画像を画面に表示させるというのは、Video4Linux2サポートの確認をする以外には有用ではないかもしれません。 ですが、それ故に、デバイスを選択し、いろいろなモードを指定できることは重要かもしれません。

オーディオデバイスの初期設定

mplayerの設定の前に、私のマシンに特有かもしれませんが、初期設定をしておきます。 私のマシンは、以下のようにオーディオデバイスが認識されています。

hdaudio0 at pci3 dev 0 function 1: HD Audio Controller
hdaudio0: interrupting at msi1 vec 0
hdaudio0: HDA ver. 1.0, OSS 4, ISS 0, BSS 0, SDO 1, 64-bit
hdafg0 at hdaudio0: ATI R6xx HDMI
hdafg0: HDMI00 2ch: Digital Out [Jack]
hdafg0: HDMI01 2ch: Digital Out [Jack]
hdafg0: 2ch/0ch 32000Hz 44100Hz 48000Hz PCM16 AC3
audio0 at hdafg0: playback
audio0: slinear_le:16 2ch 48000Hz, blk 1920 bytes (10ms) for playback
spkr1 at audio0: PC Speaker (synthesized)
wsbell at spkr1 not configured
(snip)
hdaudio1 at pci3 dev 0 function 6: HD Audio Controller
hdaudio1: interrupting at msi4 vec 0
hdaudio1: HDA ver. 1.0, OSS 4, ISS 4, BSS 0, SDO 1, 64-bit
hdafg1 at hdaudio1: Realtek product 0245
hdafg1: DAC00 2ch: Speaker [Built-In]
hdafg1: DAC01 2ch: HP Out [Jack]
hdafg1: ADC02 2ch: Mic In [Jack]
hdafg1: 2ch/2ch 44100Hz 48000Hz 96000Hz 192000Hz PCM16 PCM20 PCM24
audio1 at hdafg1: playback, capture, full duplex, independent
audio1: slinear_le:16 2ch 48000Hz, blk 1920 bytes (10ms) for playback
audio1: slinear_le:16 2ch 48000Hz, blk 1920 bytes (10ms) for recording
spkr2 at audio1: PC Speaker (synthesized)
wsbell at spkr2 not configured

一方で、/dev以下は、このようになっています。 audio0はHDMI出力なので、このままでは内蔵スピーカーからは音を出すのが面倒です。 しかも、DRMKMSのサポートがないマシンなので、そもそもHDMI経由でオーディオ出力はできません。

$ ls -l /dev/audio* /dev/sound*
lrwxr-xr-x  1 root  wheel       11 May 11  2025 /dev/audio -> /dev/audio0
crw-rw-rw-  1 root  wheel  42, 128 May 10  2025 /dev/audio0
crw-rw-rw-  1 root  wheel  42, 129 May 10  2025 /dev/audio1
crw-rw-rw-  1 root  wheel  42, 130 May 10  2025 /dev/audio2
crw-rw-rw-  1 root  wheel  42, 131 May 10  2025 /dev/audio3
lrwxr-xr-x  1 root  wheel       14 May 11  2025 /dev/audioctl -> /dev/audioctl0
crw-rw-rw-  1 root  wheel  42, 192 May 10  2025 /dev/audioctl0
crw-rw-rw-  1 root  wheel  42, 193 May 10  2025 /dev/audioctl1
crw-rw-rw-  1 root  wheel  42, 194 May 10  2025 /dev/audioctl2
crw-rw-rw-  1 root  wheel  42, 195 May 10  2025 /dev/audioctl3
lrwxr-xr-x  1 root  wheel       11 May 11  2025 /dev/sound -> /dev/sound0
crw-rw-rw-  1 root  wheel  42,   0 May 10  2025 /dev/sound0
crw-rw-rw-  1 root  wheel  42,   1 May 10  2025 /dev/sound1
crw-rw-rw-  1 root  wheel  42,   2 May 10  2025 /dev/sound2
crw-rw-rw-  1 root  wheel  42,   3 May 10  2025 /dev/sound3

cd /dev ; ln -sf audio1 audio ; ln -sf audioctl1 audioctl ; ln -sf sound1 soundと 実行しても良いのですが、audiocfg default 1とすれば、同じことをしてくれます。 結果は、以下のようになりました。 これで/dev/audioを使って、内蔵スピーカーから音を出力できることができるようにします。

$ ls -l /dev/audio* /dev/sound*
lrwxr-xr-x  1 root  wheel       11 May 11  2025 /dev/audio -> /dev/audio1
crw-rw-rw-  1 root  wheel  42, 128 May 10  2025 /dev/audio0
crw-rw-rw-  1 root  wheel  42, 129 May 10  2025 /dev/audio1
crw-rw-rw-  1 root  wheel  42, 130 May 10  2025 /dev/audio2
crw-rw-rw-  1 root  wheel  42, 131 May 10  2025 /dev/audio3
lrwxr-xr-x  1 root  wheel       14 May 11  2025 /dev/audioctl -> /dev/audioctl1
crw-rw-rw-  1 root  wheel  42, 192 May 10  2025 /dev/audioctl0
crw-rw-rw-  1 root  wheel  42, 193 May 10  2025 /dev/audioctl1
crw-rw-rw-  1 root  wheel  42, 194 May 10  2025 /dev/audioctl2
crw-rw-rw-  1 root  wheel  42, 195 May 10  2025 /dev/audioctl3
lrwxr-xr-x  1 root  wheel       11 May 11  2025 /dev/sound -> /dev/sound1
crw-rw-rw-  1 root  wheel  42,   0 May 10  2025 /dev/sound0
crw-rw-rw-  1 root  wheel  42,   1 May 10  2025 /dev/sound1
crw-rw-rw-  1 root  wheel  42,   2 May 10  2025 /dev/sound2
crw-rw-rw-  1 root  wheel  42,   3 May 10  2025 /dev/sound3

オーディオデバイスを指定する

私はpkgsrc/multimedia/mplayerで、ossとSDL-1.2、PulseAudio経由でオーディオを再生できるようにしているので、それぞれを試してみます。 他にも設定できるパラメーターはあると思いますが…。

; OSSでデフォルトのオーディオデバイスで再生する場合
$ mplayer -ao oss ./test.mp4
; OSSで/dev/audio1で再生する場合
$ mplayer -ao oss:/dev/audio1 ./test.mp4
; PulseAudio経由で再生する場合
$ mplayer -ao pulse ./test.mp4
; SDL-1.2経由でPulseAudioで再生する場合
SDL_AUDIODRIVER=pulse mplayer -ao sdl ./test.mp4
; SDL-1.2経由でOSSの/dev/audioで再生する場合
SDL_AUDIODRIVER=dsp mplayer -ao sdl ./test.mp4
; SDL-1.2経由でOSSの/dev/audioで再生する場合
SDL_AUDIODRIVER=dsp mplayer -ao sdl ./test.mp4
; SDL-1.2経由でOSSの/dev/audio1で再生する場合
$ SDL_AUDIODRIVER=dsp AUDIODEV=/dev/audio1 mplayer -ao sdl ./test.mp4

webcamを開く

webcamにもいろいろ設定はあるはずですが、以下のようにすれば、Video4Linux2サポートの確認には良さそうです。

$ mplayer tv:// -tv driver=v4l2:device=/dev/video1:width=1280:height=720:outfmt=yv12 -fps 15

おわりに

とりあえず、これでwebcamやサウンドカードの動作確認をするのには十分そうです。 でも、今日時点のNetBSD/amd64-currentだと、オーディオ出力と入力の組み合わがおかしいような…。 ちゃんと調べた方が良いかもしれません。 勘違いだと良いのですが…。

NetBSDでCDをリッピングしてみる(一応成功)

この記事は、NetBSD Advent Calendar 2025の12日目の記事です。

はじめに

furandon pigさんの10日目の記事でAudio CDのリッピングに失敗されていました。 ですが、私は過去にリッピングしていたはずです。

私の環境は、NetBSD/amd64 11.99.4にUSB 3接続のBD-Rドライブであるパイオニア製のBDR-XD08SVです。 ちなみに、いつの間にかパイオニアは光学ディスクドライブからは撤退しているように見えます。残念です。

pkgsrc/sysutils/cdrtoolsのcdda2wavコマンドを試してみる

cdrtoolsには、cdda2wavというコマンドが含まれています。 これであればリッピングできるはずです。 今回の光学ディスクドライブはcd0として認識されています。 ですが、一般ユーザーで実行したいので、まずは/dev/rcd0*のパーミッションを設定しておきます。 私が使っているユーザーはoperatorグループに所属していますので、以下のように設定すれば良いでしょう。

# chmod 660 /dev/rcd0*

その上でcdrtoolsをインストールしましょう。以下のように実行すれば良いでしょう。

# cd /usr/pkgsrc/sysutils/cdrtools
# make install

cdda2wav(1)のmap pageにあるように以下のように実行すれば良いでしょう。

$ cdda2wav -vall cddb=0 speed=4 -paranoia paraopts=proof -B
cdda2wav: Insufficient 'file read' privileges. You will not be able to open all needed devices.
cdda2wav: Insufficient 'file write' privileges. You will not be able to open all needed devices.
cdda2wav: Insufficient 'device' privileges. You may not be able to send all needed SCSI commands, this my cause various unexplainable problems.
cdda2wav: Insufficient 'priocntl' privileges. You may get jitter.
cdda2wav: Insufficient 'network' privileges. You will not be able to do remote SCSI.
No target specified, trying to find one...
Using dev=31,0,0.
Type: ROM, Vendor 'PIONEER ' Model 'BD-RW   BDR-XD08' Revision '1.02' MMC+CDDA
274432 bytes buffer memory requested, transfer size 61440 bytes, 4 buffers, 23 sectors
#Cdda2wav version 2024/03/18 3.02_netbsd_11.99.4_amd64_x86_64, real time sched., soundcard, libparanoia support
cdda2wav: Bad status from freedb server during hello: 500 Command syntax error.
.
cdda2wav: Bad status from freedb server during quit: 500 Unrecognized command, closing connection.
.
AUDIOtrack pre-emphasis  copy-permitted tracktype channels
      1-11           no              no     audio    2
Table of Contents: total tracks:11, (total time 48:35.00)
  1.( 2:00.42),  2.( 3:58.73),  3.( 4:58.40),  4.( 4:28.20),  5.( 4:12.57),
  6.( 4:39.13),  7.( 4:55.05),  8.( 4:43.70),  9.( 4:47.17), 10.( 3:56.45),
 11.( 5:53.68)

Table of Contents: starting sectors
  1.(       0),  2.(    9042),  3.(   26965),  4.(   49355),  5.(   69475),
  6.(   88432),  7.(  109370),  8.(  131500),  9.(  152795), 10.(  174337),
 11.(  192082), lead-out(  218625)
CDINDEX discid: xxh_sS61wqdXnYPsHKLlN3v5y1c-
CDDB discid: 0x830b630b
CD-Text: not detected
CD-Extra: not detected
Media catalog number: 4988022106978
T:  2 ISRC: JP-TA0-92-20030
T:  3 ISRC: JP-TA0-92-20040
T:  4 ISRC: JP-TA0-92-20050
T:  5 ISRC: JP-TA0-92-20060
T:  6 ISRC: JP-TA0-92-20070
T:  7 ISRC: JP-TA0-92-20080
T:  8 ISRC: JP-TA0-92-20090
T:  9 ISRC: JP-TA0-92-20100
T: 10 ISRC: JP-TA0-92-20110
T: 11 ISRC: JP-TA0-92-20120

index scan: 11...
samplefile size will be 514206044 bytes.
recording 2915.0000 seconds stereo with 16 bits @ 44100.0 Hz ->'audio'...
using c2check to verify reads.
using lib paranoia for reading.
cdda2wav: Operation not permitted. Cannot set posix realtime scheduling policy.
percent_done:
100%  track  1 recorded successfully
100%  0 rderr, 0 skip, 0 atom, 0 edge, 0 drop, 0 dup, 0 drift, 0 0 c2
100%  896 reads(212.3%) 24 overlap(20 .. 20)
100%  track  2 recorded successfully
100%  0 rderr, 0 skip, 0 atom, 0 edge, 0 drop, 0 dup, 0 drift, 0 0 c2
100%  1736 reads(207.6%) 62 overlap(20 .. 20)
100%  track  3 recorded successfully
100%  0 rderr, 0 skip, 0 atom, 0 edge, 0 drop, 0 dup, 0 drift, 0 0 c2
100%  2184 reads(209.0%) 78 overlap(20 .. 20)
100%  track  4 recorded successfully
100%  0 rderr, 0 skip, 0 atom, 0 edge, 0 drop, 0 dup, 0 drift, 0 0 c2
100%  1960 reads(208.7%) 70 overlap(20 .. 20)
100%  track  5 recorded successfully
100%  0 rderr, 0 skip, 0 atom, 0 edge, 0 drop, 0 dup, 0 drift, 0 0 c2
100%  1792 reads(202.6%) 64 overlap(20 .. 20)
100%  track  6 recorded successfully
100%  0 rderr, 0 skip, 0 atom, 0 edge, 0 drop, 0 dup, 0 drift, 0 0 c2
100%  2072 reads(212.1%) 74 overlap(20 .. 20)
100%  track  7 recorded successfully
100%  0 rderr, 0 skip, 0 atom, 0 edge, 0 drop, 0 dup, 0 drift, 0 0 c2
100%  2128 reads(206.1%) 76 overlap(20 .. 20)
100%  track  8 recorded successfully
100%  0 rderr, 0 skip, 0 atom, 0 edge, 0 drop, 0 dup, 0 drift, 0 0 c2
100%  2072 reads(208.5%) 74 overlap(20 .. 20)
100%  track  9 recorded successfully
100%  0 rderr, 0 skip, 0 atom, 0 edge, 0 drop, 0 dup, 0 drift, 0 0 c2
100%  2072 reads(206.1%) 74 overlap(20 .. 20)
100%  track 10 recorded successfully
100%  0 rderr, 0 skip, 0 atom, 0 edge, 0 drop, 0 dup, 0 drift, 0 0 c2
100%  1736 reads(209.6%) 62 overlap(20 .. 20)
100%  track 11 recorded successfully
100%  0 rderr, 0 skip, 0 atom, 0 edge, 0 drop, 0 dup, 0 drift, 0 0 c2
100%  2530 reads(204.2%) 92 overlap(20 .. 20)
$ ls
audio_01.inf audio_03.inf audio_05.inf audio_07.inf audio_09.inf audio_11.inf
audio_01.wav audio_03.wav audio_05.wav audio_07.wav audio_09.wav audio_11.wav
audio_02.inf audio_04.inf audio_06.inf audio_08.inf audio_10.inf
audio_02.wav audio_04.wav audio_06.wav audio_08.wav audio_10.wav

audio_01.wavからaudio_11.wavが生成できました。

できたwavファイルをmp3ファイルに変換する

MP3の特許は、少なくとも日本では既の期限を迎えているようです。 ですので、MP3にエンコードしても特許侵害にはならないでしょう。 と言うことで、pkgsrc/audio/lameを使うことにします。 以下のようにインストールすれば良いでしょう。

# cd /usr/pkgsrc/audio/lame

おそらくとても贅沢な気がするのですが、最近のamd64なマシンにとってMP3エンコードなど負荷にもならないと思います。 以下のようにMP3ファイルを生成しました。

$ for f in *.wav
do lame -q0 -b256 $f `basename $f .wav`.mp3
done
LAME 3.100 64bits (http://lame.sf.net)
Using polyphase lowpass filter, transition band: 19383 Hz - 19916 Hz
Encoding audio_01.wav to audio_01.mp3
Encoding as 44.1 kHz j-stereo MPEG-1 Layer III (5.5x) 256 kbps qval=0
    Frame          |  CPU time/estim | REAL time/estim | play/CPU |    ETA
  4617/4617  (100%)|    0:13/    0:13|    0:13/    0:13|   8.6830x|    0:00
-------------------------------------------------------------------------------
   kbps        LR    MS  %     long switch short %
  256.0       99.0   1.0        88.6   5.2   6.2
Writing LAME Tag...done
ReplayGain: +4.8dB
LAME 3.100 64bits (http://lame.sf.net)
Using polyphase lowpass filter, transition band: 19383 Hz - 19916 Hz
Encoding audio_02.wav to audio_02.mp3
(snip)

mp3ファイルのタグを設定し、ファイル名を変更する

pkgsrc/audio/easytagを使うと、MP3にIDv2のタグを設定すると同時に、ファイル名も「アーティスト名-曲名」等に変更することができます。 pkgsrc/audio/easytagはヘルプを表示するためにpkgsrc/misc/yelp3を利用するため、間接的にpkgsrc/www/webkit-gtkを利用することになります。 自分でpkgsrc/audio/easytagをビルドしてインストールするのであれば、以下のようにpkgsrc/www/webkit-gtkは使わないようにインストールした方が良いかもしれません。

# cd /usr/pkgsrc/audio/easytag
# make PKG_OPTIONS.easytag=-doc install

おわりに

でも良く考えるとpkgsrc/audio/abcdeは、私が以前試した時に動いていたはずです (abcde -d /dev/rcd0)。 もしかしたらNetBSDでは、/dev/cd0ではなく/dev/rcd0を使わないといけないというだけかもしれません。 他のGUI付きのソフトウェアの方が便利かもしれません。 いずれ試してみたいと思います。

USBシリアルアダプターをUEFIブートの場合にconsoleとして使う機能を試してみる

この記事は、NetBSD Advent Calendar 2025の7日目の記事です。

はじめに

2025年10月9日のmanu@のコミットと関連するコミットで、UEFIブートの際にuftdi(4)として認識されるUSBシリアルコンバーターをconsoleとして利用できるようになっていました。 ちょうど手元にFTDI製のチップを使ったUSBシリアルコンバーターを持っていましたので、試してみました。

本来は、DDBとかも使えるらしいのですが、今回はシリアルコンソール経由でログインするのみです。

初期設定

NetBSD/amd64 l11.99.4をインストールしたラップトップに、Windows 11 25H2上のPuTTYからログインしてみます。 単にログインするだけであれば、NetBSD側で以下のように設定すれば良いでしょう。

# vi /etc/ttys
(snip)
ttyU0   "/usr/libexec/getty std.115200" vt100 on secure

こうすれば、115200 bpsで通信するPuTTYでloginプロンプトを得ることができます。 具体的には下図のように設定します。

この設定は、以下の設定をしても必要ですので、この時点で設定して置くのが良いでしょう。

ucom0 at uftdi0をconsoleに設定する

以下のように認識されるデバイスをNetBSD側に接続してあります。

uftdi0 at uhub9 port 1 configuration 1 interface 0
uftdi0: FTDI (0x0403) USB HS SERIAL CONVERTER (0x6001), rev 1.10/4.00, addr 4
ucom0 at uftdi0 portno 0

その上で再起動させ、UEFIブートローダーで以下のように設定して、起動させます。

> kconsdev ucom0,115200
> boot

Windows 11上のPuTTYでは、ucom0が認識される所からブートメッセージが表示されます。

[   3.7030449] ucom0: console
[   4.1930474] uhidev1 at uhub8 port 2 configuration 1 interface 0
[   4.1930474] uhidev1: ActionStar (0x2101) product 0201 (0x0201), rev 1.10/1.00, addr 5, iclass 3/0
[   4.2030475] uhid7 at uhidev1: input=2, output=2, feature=0
[   4.7030507] uhidev2 at uhub8 port 3 configuration 1 interface 0
[   4.7030507] uhidev2: Logitech (0x046d) USB Receiver (0xc53f), rev 2.00/55.02, addr 6, iclass 3/1
[   4.7130541] ukbd0 at uhidev2
[   4.7130541] wskbd1 at ukbd0 mux 1
[   4.7330511] uhidev3 at uhub8 port 3 configuration 1 interface 1
[   4.7330511] uhidev3: Logitech (0x046d) USB Receiver (0xc53f), rev 2.00/55.02, addr 6, iclass 3/1
[   4.7430515] uhidev3: 8 report ids
[   4.7430515] ums0 at uhidev3 reportid 2: 16 buttons, W and Z dirs
[   4.7430515] wsmouse2 at ums0 mux 0
[   4.7430515] uhid8 at uhidev3 reportid 3: input=4, output=0, feature=0
[   4.7430515] uhid9 at uhidev3 reportid 4: input=1, output=0, feature=0
[   4.7430515] uhid10 at uhidev3 reportid 8: input=1, output=0, feature=0
[   4.7430515] uhidev4 at uhub8 port 3 configuration 1 interface 2
[   4.7430515] uhidev4: Logitech (0x046d) USB Receiver (0xc53f), rev 2.00/55.02, addr 6, iclass 3/0
[   9.7530773] uhidev4: no report descriptor
[   9.7530773] swwdog0: software watchdog initialized
[   9.7530773] usb8 at vhci0: USB revision 2.0
[   9.7730770] uhub10 at usb8: NetBSD (0x0000) VHCI root hub (0x0000), class 9/0, rev 2.00/1.00, addr 1
[   9.7730770] usb9 at vhci1: USB revision 2.0
[   9.7930776] uhub11 at usb9: NetBSD (0x0000) VHCI root hub (0x0000), class 9/0, rev 2.00/1.00, addr 1
[   9.7930776] usb10 at vhci2: USB revision 2.0
[   9.8130773] uhub12 at usb10: NetBSD (0x0000) VHCI root hub (0x0000), class 9/0, rev 2.00/1.00, addr 1
[   9.8130773] usb11 at vhci3: USB revision 2.0
[   9.8330781] uhub13 at usb11: NetBSD (0x0000) VHCI root hub (0x0000), class 9/0, rev 2.00/1.00, addr 1
[   9.8330781] usb12 at vhci4: USB revision 2.0
[   9.8530774] uhub14 at usb12: NetBSD (0x0000) VHCI root hub (0x0000), class 9/0, rev 2.00/1.00, addr 1
[   9.8530774] usb13 at vhci5: USB revision 2.0
[   9.8730810] uhub15 at usb13: NetBSD (0x0000) VHCI root hub (0x0000), class 9/0, rev 2.00/1.00, addr 1
[   9.8730810] usb14 at vhci6: USB revision 2.0
[   9.8930773] uhub16 at usb14: NetBSD (0x0000) VHCI root hub (0x0000), class 9/0, rev 2.00/1.00, addr 1
[   9.8930773] usb15 at vhci7: USB revision 2.0
[   9.9130776] uhub17 at usb15: NetBSD (0x0000) VHCI root hub (0x0000), class 9/0, rev 2.00/1.00, addr 1
[   9.9130776] WARNING: 4 errors while detecting hardware; check system log.
[   9.9130776] boot device: ld0
[   9.9130776] root on dk1 dumps on dk2
[   9.9130776] root file system type: ffs
[   9.9130776] kern.module.path=/netbsd/modulesystem type: ffTue Dec  9 10:46:12 -00 2025
9130776] root file system type: ffTue Dec  9 10:46:12 -00 2025
Starting root file system check:
/dev/rdk1: file system is clean; not checking
Starting devpubd.
Setting sysctl variables:
ddb.onpanic: 1 -> 0
swapctl: setting dump device to /dev/dk2
swapctl: adding /dev/dk2 as swap device at priority 0
Starting file system checks:
/dev/rdk4: file system is clean; not checking
/dev/rdk3: file system is clean; not checking
Loaded entropy from /var/db/entropy-file.
Waiting for entropy...done
Setting tty flags.
Starting network.
Hostname: castella
IPv6 mode: host
Configuring network interfaces:.
Adding interface aliases:.
Waiting for duplicate address detection to finish...
Building databases: dev, utmp, utmpx.
Keyboard encoding -> us.swapctrlcaps
Starting syslogd.
Mounting all file systems...
Clearing temporary files.
Checking quotas: done.
swapctl: setting dump device to /dev/dk2
Starting virecover.
Checking for core dump...
savecore: no core dump
Starting local daemons:.
Updating motd.
Starting pcscd.
/etc/rc.d/pcscd exited with code 1
Starting powerd.
Starting sshd.
Starting postfix.
postfix/postlog: starting the Postfix mail system
Starting multiskkserv.
Setting mixerctl variables...
mixerctl: field record.mic2 does not exist
Starting inetd.
Starting dbus.
Starting cupsd.
Starting cron.
The following components reported failures:
    /etc/rc.d/pcscd
See /var/run/rc.log for) (ttyU0)

login: 

代わりに、NetBSDのディスプレイにはloginプロンプトのみが表示されます。

pcscdの起動が失敗するのは別の問題なようです。

NetBSD上のpkgsrc/www/firefoxでwebcamを使えない問題を解析した

この記事は、NetBSD Advent Calendar 2025の5日目の記事です。

はじめに

いまいちどの時点からか分からなくなってしまったのですが、pkgsrc/www/firefoxでは、私の今利用しているHP Envy 14 fa0000にインストールしたNetBSD/amd64-currentではwebcamを利用できなくなってしまっていました。 もしかしたら、PCを変えたタイミングだったかもしれませんが、全く分かりません。

いずれにしても、WebRTCでwebcamの映像を使えないのは残念です。 しばらく放置してしまっていましたが、直すことにしました。

認識されないのを確認できるウェブサイトを特定する

HP Envy 14にインストールされたNetBSD/amd64-currentでは、以下のようにvideo0からvideo3の4つのデバイスが認識されます。

uvideo0 at uhub3 port 1 configuration 1 interface 0: SunplusIT Inc (0x04f2) HP 5MP Camera (0xb7fe), rev 2.01/0.06, addr 1
video0 at uvideo0: SunplusIT Inc (0x04f2) HP 5MP Camera (0xb7fe), rev 2.01/0.06, addr 1
video1 at uvideo0: SunplusIT Inc (0x04f2) HP 5MP Camera (0xb7fe), rev 2.01/0.06, addr 1
uvideo1 at uhub3 port 1 configuration 1 interface 2: SunplusIT Inc (0x04f2) HP 5MP Camera (0xb7fe), rev 2.01/0.06, addr 1
video2 at uvideo1: SunplusIT Inc (0x04f2) HP 5MP Camera (0xb7fe), rev 2.01/0.06, addr 1
video3 at uvideo1: SunplusIT Inc (0x04f2) HP 5MP Camera (0xb7fe), rev 2.01/0.06, addr 1

ただし、pkgsrc/multimedia/mplayerで確認してみると、video1とvideo3だけが使えます。 ちなみに、確認した方法は以下のようです。

$ mplayer tv:// -tv device=/dev/video1
$ mplayer tv:// -tv device=/dev/video3

mplayerでのvideo(4)デバイスの動作確認の方法は、別に書いていた方が良いかもしれません。

これまでは、getUserMedia / getDisplayMedia Test Pageを使って来たのですが、 これはそもそも複数のwebcamを選択することはできないので、適切ではありません。 そこで、WebRTC samplesSelect sources & outputsを利用することにします。 ここでは、webcamを選択することができます。 ちなみに、現時点ではwebcamを選択するまでもなくエラーになってしまいます。

エラーにつながる箇所を特定する

広大なFirefoxのソースコードベースの中で、getUserMediaでそもそもエラーになってしまう箇所の当たりを付けるのは大変なはずですが、 third_party/libwebrtc以下にしかwebcamを認識するロジックはないはずなのと、 おそらくVideo4Linix2のioctlでエラーになっていて、それによりwebcamを選択するまでもなくエラーになっているはずということは当たりがついています。 なので、third_party/libwebrtc以下にあるmoz.buildを読んで、NetBSDである場合にbuildされるsource codeのうち、ioctlでVIDIOC_*を第2引数に与えている箇所を探せば良さそうと思いました。

と言うことは、grep -r "ioctl.*VIDIOC_" ${WRKSRC}/third_party/libwebrtcを実行した上で、moz.buildと照合すれば良さそうです。

$ ugrep -r "ioctl.*VIDIOC_" third_party/libwebrtc
third_party/libwebrtc/modules/video_capture/linux/device_info_v4l2.cc: (snip)
(snip)
third_party/libwebrtc/modules/video_capture/linux/video_capture_v4l2.cc: (snip)
(snip)

moz.buildを見るまでもなく、NtBSDでも使っているファイルです。 と言うことで、各ioctlの結果が分かるようにprintfを入れてbuildしてみました。

解析の結果と修正案

結果として、以下の188行目のioctlが返すfmtに返って来ている内容が想定外であり、そのために全てのwebcamが認識されなっくなっていました。

$ cat -n third_party/libwebrtc/modules/video_capture/linux/video_capture_v4l2.cc
(snip)
   181    // Enumerate image formats.
   182    struct v4l2_fmtdesc fmt;
   183    int fmtsIdx = nFormats;
   184    memset(&fmt, 0, sizeof(fmt));
   185    fmt.index = 0;
   186    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
   187    RTC_LOG(LS_INFO) << "Video Capture enumerats supported image formats:";
   188    while (ioctl(_deviceFd, VIDIOC_ENUM_FMT, &fmt) == 0) {
   189      RTC_LOG(LS_INFO) << "  { pixelformat = " << GetFourccName(fmt.pixelformat)
   190                       << ", description = '" << fmt.description << "' }";
   191      // Match the preferred order.
   192      for (int i = 0; i < nFormats; i++) {
   193        if (fmt.pixelformat == fmts[i] && i < fmtsIdx)
   194          fmtsIdx = i;
   195      }
   196      // Keep enumerating.
   197      fmt.index++;
   198    }
(snip)

更に良く見ていくと、以下のように最初はioctl(fd, VIDIOC_QUERYCAP, &cap)でのみwebcamが利用可能か認識して使えるとなっているのに、この箇所でエラーになってしまうという流れになっており、これが想定外なようです。

$ cat -n third_party/libwebrtc/modules/video_capture/linux/video_capture_v4l2.cc
    86    /* detect /dev/video [0-63] entries */
    87    int n;
    88    for (n = 0; n < 64; n++) {
    89      snprintf(device, sizeof(device), "/dev/video%d", n);
    90      if ((fd = open(device, O_RDONLY)) != -1) {
    91        // query device capabilities
    92        struct v4l2_capability cap;
    93        if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == 0) {
    94          if (cap.bus_info[0] != 0) {
    95            if (strncmp((const char*)cap.bus_info,
    96                        (const char*)deviceUniqueIdUTF8,
    97                        strlen((const char*)deviceUniqueIdUTF8)) ==
    98                0) {  // match with device id
    99              close(fd);
   100              found = true;
   101              break;  // fd matches with device unique id supplied
   102            }
   103          }
   104        }
   105        close(fd);  // close since this is not the matching device
   106      }
   107    }
   108    if (!found) {
(snip)

と言うことで、最初からioctl(_deviceFd, VIDIOC_ENUM_FMT, &fmt)もチェックしておけば良さそうです。

--- third_party/libwebrtc/modules/video_capture/linux/video_capture_v4l2.cc.orig	2025-12-05 17:43:20.000000000 +0000
+++ third_party/libwebrtc/modules/video_capture/linux/video_capture_v4l2.cc
@@ -90,18 +90,28 @@ int32_t VideoCaptureModuleV4L2::Init(con
     if ((fd = open(device, O_RDONLY)) != -1) {
       // query device capabilities
       struct v4l2_capability cap;
+#if defined(VIDIOC_QUERYCAP)
       if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == 0) {
         if (cap.bus_info[0] != 0) {
           if (strncmp((const char*)cap.bus_info,
                       (const char*)deviceUniqueIdUTF8,
                       strlen((const char*)deviceUniqueIdUTF8)) ==
               0) {  // match with device id
-            close(fd);
-            found = true;
-            break;  // fd matches with device unique id supplied
+            struct v4l2_fmtdesc fmt;
+            memset(&fmt, 0, sizeof(fmt));
+            fmt.index = 0;
+            fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+            if (ioctl(fd, VIDIOC_ENUM_FMT, &fmt) == 0) {
+              if (fmt.pixelformat != 0) {
+                close(fd);
+                found = true;
+                break;  // fd matches with device unique id supplied
+              }
+            }
           }
         }
       }
+#endif
       close(fd);  // close since this is not the matching device
     }
   }

とりあえず、pkgsrc/www/firefoxを146.0にアップデートする際には含めておきたいと思います。 ですが、そもそもこのwebcamのvideo0とvideo2をサポートした方が良いかもしれません。

NetBSD/amd64上でFree Pascalでプログラムを書いてみる

この記事は、NetBSD Advent Calendar 2025の1日目の記事です。

Free Pascalとは?

Free Pascalとは、オープンソースのPascalとObject Pascalコンパイラーで、 オリジナルのPascal言語だけでなく、Turbo PascalのPascal言語やDelphiのObject Pascal言語もサポートしているようです。

私はPascalの熱心なユーザーであったことはないのですが、書籍の中では疑似コードとしてPascal風のソースコードを目にしたことは数多くあります。

Free Pascalとしては、NetBSDをサポートしていたようなのですが、pkgsrcには取り込まれていなかったようです。 Free Pascalコンパイラーを使っている人にとっては当たり前なのかもしれませんが、NetBSD上でコンパイルする場合に 必要だった事項を記載しておきたいと思います。

Free Pascalコンパイラーをインストールする

NetBSD/amd64でFree Pascalコンパイラーのバージョン3.2.2を利用することができます。 pkgsrc/lang/fpcとしてインポートされており、 Free Pascalのコンパイラーは、/usr/pkg/bin/fpcとしてインストールされます。 以下のように実行してインストールすれば良いでしょう。

# cd /usr/pkgsrc/lang/fpc
# make install

また、以下のように実行すると、fpcのバージョンを確認することができます。

$ fpc
Free Pascal Compiler version 3.2.2 [2025/12/08] for x86_64
Copyright (c) 1993-2021 by Florian Klaempfl and others
fpc [options] <inputfile> [options]
 Only options valid for the default or selected platform are listed.
(以下略)

初期設定

まず、Free Pascalでプログラミングするために使うディレクトリーを作り、そのディレクトリーへ移動します。

$ mkdir free-pascal
$ cd free-pascal

次に、以下のように実行して、fpc.cfgという設定ファイルを作成します。 これがfpcコマンドの実行時に参照されるファイルで、この中で標準的な設定が定義されています。 個々をコマンドライン引数でfpcへ渡しても良いのかもしれませんが、 繰り返し入力するには、相当長いコマンドライン引数になりそうです。

$ fpcmkcfg -d basepath=/usr/pkg/lib/fpc/3.2.2 > fpc.cfg

サンプルプログラムをコンパイルしてみる

Hello worldは、以下のように書けば良いようです。 hello.pasとして保存しておきます。

program Hello;
begin
  writeln ('Hello, world.');
end.

以下のようにコンパイルし、実行します。

$ fpc hello.pas
$ ls hello*
hello hello.o hello.pas
# ./hello
Hello, world.

もう少し複雑なものとして、階乗を再帰で実装してみます。 factorial.pasとして保存しておきます。

program factorial;

function fact(n: integer): longint;
begin
    if (n = 0) then
        fact := 1
    else
        fact := n * fact(n - 1);
end;

var
    n: integer;

begin
    for n := 0 to 16 do
        writeln(n, '! = ', fact(n));
end.

以下のようにコンパイルし、実行します。

$ fpc factorial.pas
Free Pascal Compiler version 3.2.2 [2025/12/08] for x86_64
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: NetBSD for x86-64
Compiling factorial.pas
Linking factorial
17 lines compiled, 0.1 sec
$ ls factorial*
factorial       factorial.o     factorial.pas
$ ./factorial
0! = 1
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
10! = 3628800
11! = 39916800
12! = 479001600
13! = 1932053504
14! = 1278945280
15! = 2004310016
16! = 2004189184

おわりに

Pascalコンパイラーとしては、pkgsrcにはGNU Pascal Compiler (GPC)もpkgsrc/lang/gpcとして収録されているようです。 こちらもいずれ使ってみたいと思います。

NetBSD-currentのwscons(4)で256色表示を試してみる

この記事は、NetBSD Advent Calendar 2025の2日目の記事です。

2025年11月2日のniaのコミットで、 wscons(4)でのVT100エミュレーションで、256色表示がサポートされました。 NetBSD/amd64-currentで実際に確認してみました。

今回は、VMware Workstation Pro 25H2 for Microsoft WindowsでNetBSD/amd64-currentを動かしてみました。

これでw3mでウェブブラウジングした際に便利だろうと思ったのですが、Google検索がw3mで利用できなくなってしまったため、 あまり役立てることができていません。

SONY WH-1000XM6をBluetooth LE Audio LC3コーデックをサポートしたBluetoothトランスミッターFlooGoo FMA120と一緒に使ってみる

SONYのWH-1000XM6というヘッドホンを持っている。 これはBluetooth接続のヘッドホンで、通話用のマイクも搭載されている。 もちろんclassic BluetoothのHFPとかで、この通話用のマイクは利用できるのだが、 コーデックがSBCであり、音質は良くない。 もちろん、SBCで達成することのできる最高の音質になっているとは思うが…。

一方で、Bluetooth LE Audioもサポートしていて、LC3コーデックによる 通話も可能なことになっている。 ただ、これがHFPでLC3を使う拡張があったと思うので、それを使っているのか、 あるいは、LE Audioには独自のマイクを扱うプロトコルがあるのかは、 全く理解できていない。

通話をせず、本当にヘッドホンとして音を聞きたい場合であれば、 A2DPを使えば良い。WH-1000XM6では、SBCだけでなくAACとLDACがサポートされているので、 AndroidのスマートフォンやAmazon Fireタブレット、iPhone、Windows 11 PCでも 良い音質で音を聞くことはできる。 ただ、ビデオを見ている場合には、基本的には音は遅延する。 LC3の場合には、音の遅延は小さくできることになっているはずである。

私の手元にあるデバイスで、LE Audioをサポートしているものはないので、 LC3を使った場合の音質や遅延について体感できずにいた。

LE Audioは何年か前のBluetooth 5系統の仕様で定められているはずで、 多くのBluetoothホストコントローラーはそのバージョンのBluetoothの 仕様を実装済みのはずである。 ただ、LE AUdioはA2DPのように後からBluetoothスタックに付け足してサポートできず、 Bluetoothをスタックに大きく手を入れないと実装できないと 聞いた気もする。 そのせいかは分からないが、LE Audioが使えるようになるUSB接続の Bluetoothドングルというのも売られているようには見えない。 Bluetooth 5.4対応のBluetoothドングルというを買ってみたが、LE Audioをサポートしてはいなかった。

では何が売られているかと言うと、種類数は少ないのだが、トランスミッター と呼ばれる機器が売られている。 これは、USBでPC等に接続するデバイスで、PCで動くOSからは、 USB Audio classのデバイスとして見え、そのトランスミッターが独自に LE Audio機器とペアリングするというものである。 LE Audioの登場する前から、種類数は少ないが、こういうデバイスは売られていて、 私もCreative製のBT-W3を持っている。 だが、BT-W3はSBCとAptX Low Latency、AptX HD、AptXしかサポートしておらず、 私はAptX系のコーデックを利用するBluetooth機器は持っていないので、あまり役立てることはできなかった。

LE Audioをサポートするトランスミッターというのは数少なく、 どれもQualcommのチップを使っているようである。 Eppfun製のものは日本でも入手が容易で、比較的安価であるようだが、 ヘッドホン側もQualcommのチップを使っていないと、接続できないという コメントをどこかで見た気がする。

SONY WH-1000XM6がどのようなチップを使っているのか分かっていないが、 前世代のWH-1000XM5はXtensaのチップを搭載していたような気がする。 少なくともQualcommのチップが利用されていると期待できないように思われる。

と言うことでWH-1000XM6をサポートしていると明確に書かれているFlooGoo FMA120を購入してみた。 Amazon.comで購入すると、Amazon.co.jpより相当安く買えるので、Amazon.comで購入した。

結果としては、全く問題なくLC3コーデックで接続でき、遅延も気になることはなく、非常に満足している。 NetBSD/amd64-currentに接続したdmesgは以下のようである。 FMA120自体は、USB Audio Class 1.0のデバイスとして認識される。 FMA120の設定は、USB to RS-232Cコンバーターとして見えているデバイス経由で実施されるようだ。 Microsoft Storeでダウンロードできる設定アプリケーションは、これを使っているようだ。

ただ、このdmesgを見ると、FMA120もQualcommのチップを使っているようだ。 なので、EppfunのトランスミッターでWH-1000XM6をサポートできないという訳はなさそうだ。

NetBSD castella 11.99.3 NetBSD 11.99.3 (LEAFFOX1) #1: Wed Sep 24 11:21:54 JST 2025  ryoon@castella:/usr/world/11.99/amd64/obj/sys/arch/amd64/compile/LEAFFOX1 amd64 x86_64
(snip)
uhub10 at uhub1 port 1: Cambridge Silicon Radio (0x0a12) product 4010 (0x4010), class 9/0, rev 2.00/21.18, addr 3
uhub10: 4 ports with 0 removable, bus powered
uhidev6 at uhub10 port 1 configuration 1 interface 0
uhidev6: Qualcomm (0x0a12) QCC3086 USB Dongle (0x4007), rev 2.00/30.91, addr 4, iclass 3/0
uhidev6: 24 report ids
uhid17 at uhidev6 reportid 1: input=2, output=0, feature=0
uhid18 at uhidev6 reportid 2: input=2, output=0, feature=0
uhid19 at uhidev6 reportid 9: input=0, output=1, feature=0
uhid20 at uhidev6 reportid 23: input=0, output=1, feature=0
uhid21 at uhidev6 reportid 24: input=0, output=1, feature=0
uhidev7 at uhub10 port 1 configuration 1 interface 1
uhidev7: Qualcomm (0x0a12) QCC3086 USB Dongle (0x4007), rev 2.00/30.91, addr 4, iclass 3/0
uhidev7: 32 report ids
uhid22 at uhidev7 reportid 1: input=0, output=62, feature=0
uhid23 at uhidev7 reportid 2: input=16, output=0, feature=0
uhid24 at uhidev7 reportid 3: input=0, output=0, feature=62
uhid25 at uhidev7 reportid 4: input=0, output=0, feature=62
uhid26 at uhidev7 reportid 5: input=0, output=254, feature=0
uhid27 at uhidev7 reportid 6: input=12, output=0, feature=0
uhid28 at uhidev7 reportid 7: input=0, output=446, feature=0
uhid29 at uhidev7 reportid 8: input=446, output=0, feature=0
uhid30 at uhidev7 reportid 9: input=11, output=0, feature=0
uhid31 at uhidev7 reportid 32: input=0, output=0, feature=255
uaudio0 at uhub10 port 1 configuration 1 interface 2
uaudio0: Qualcomm (0x0a12) QCC3086 USB Dongle (0x4007), rev 2.00/30.91, addr 4
uaudio0: ignored descriptor type 11 subtype 5
uaudio0: audio rev 1.00
audio2 at uaudio0: playback, capture, full duplex, independent
audio2: slinear_le:16 2ch 48000Hz, blk 11520 bytes (60ms) for playback
audio2: slinear_le:16 1ch 48000Hz, blk 5760 bytes (60ms) for recording
spkr3 at audio2: PC Speaker (synthesized)
wsbell at spkr3 not configured
umodem0 at uhub10 port 1 configuration 1 interface 5
umodem0: Qualcomm (0x0a12) QCC3086 USB Dongle (0x4007), rev 2.00/30.91, addr 4, iclass 2/2
umodem0: data interface 6, has CM over data, has break
umodem0: status change notification available
ucom1 at umodem0 portno 2

NetBSD上のmplayerで、audioデバイスとvideoデバイスを指定して表示させる

この記事は、 NetBSD Advent Calendar 2025 の14日目の記事です。 はじめに mplayerで出力するオーディオデバイスを指定する方法は、pkgsrc/multimedia/mplayerをpulseaudioオプションを有効にして使...