やっぱりZOOT Nativeはやめた。

NVR510に切り替えてみた。で、Yamaha NVR510を導入したエントリを書きました。
その後、それまで契約していた ZOOT NEXT を解約して ZOOT Native に切り替える…つもりだったのですが。実は11月で ZOOT Native は解約しました。

切り替えるにはconfigをいちいちいじらないといけないのですが、ちゃんとテストしないとと思い、テストしてみました。
以下は現在の状況ですが、ダウンストリームで700Mbps、アップストリームで340Mbpsと、非常に高速です。一般的には PPPoE は IPoE よりも遅い、と言われているようなのですが、うちの場合にはどちらもまったく同じ程度の速度でした。
ただし、これは NVR510 に切り替えてからのことで、それまで使っていた ATermではここまでの速度は出ませんでした。だいたいこの5分の1程度でしょうか。
ともあれ、PPPoE でも IPoE でも速度はほとんど変わらないことがわかりました。

ではなぜ NEXT から Native にしなかったかというと、固定IPの DNS 登録が絡んでいます。

うちでは Gonbei で独自にドメインを取得しています。これまで、そのドメインでサーバを運用していました。ところが Native にすると IPアドレス自体は外部からもアクセスできるのですが、ドメイン名が引けません。なにやら技術上の問題があるようで、InterlinkのFAQにもあまり詳しく書いてませんが Native で固定IPサービスを利用しても、Gonbei への登録ができないようです。

ということで、NEXTに戻ったのでした。


SQLite3で正規表現してみる。

プライベートで作っているDB、別にMySQLでもMariaDBでもなんでもいいんですが、簡単なのでSQLite3を使うことにしました。
用途はビデオのタイトルと説明のリストです。録画したものがどこにあるか、的な。

ところが、登録されてるのに引っかかってこないものがあることに気づきました。まあずばり言ってしまうと "DUNE" なんですが。いわゆる全角アルファベットで、しかも文字エンコーディングは UTF-8 です。そして要望としては、"dune" でも "DUNE" でも "DUNE" でも "デューン" でも見つかってほしいな、と。

そうなると、プログラマ的には「正規表現で探せばいいじゃん」と思いつきます。関係ないですが「じゃん」を使うのは東京近郊らしいですね。関係ないですけど。

ところで、ふつうにSQL文だと LIKE を使いますが、最近は REGEXP 演算子なるものもあるようです。が、SQLite3 で
SELECT * FROM vedeo_list WHERE title REGEXP "DUNE|DUNE|dune|デューン";
などとやると、
no such function: regexp
と言われます。

SQLiteのドキュメントを見ると、
The REGEXP operator is a special syntax for the regexp() user function. No regexp() user function is defined by default and so use of the REGEXP operator will normally result in an error message. If an application-defined SQL function named "regexp" is added at run-time, then the "X REGEXP Y" operator will be implemented as a call to "regexp(Y,X)".

とあります。 Google翻訳さんにお願いすると、

REGEXP 演算子は、regexp() ユーザー関数の特別な構文です。 デフォルトでは regexp() ユーザー関数は定義されていないため、REGEXP 演算子を使用すると、通常はエラー メッセージが表示されます。 「regexp」というアプリケーション定義の SQL 関数が実行時に追加されると、「X REGEXP Y」演算子が「regexp(Y,X)」の呼び出しとして実装されます。

と訳してくれました。どうやらユーザ関数を定義しないとだめっぽいです。 一応 ext/misc/regexp.c というファイルはソースツリーにあるので、DLLかなんかの形であるのかな?とPythonのディレクトリを見てみると、DLLsディレクトリに sqlite3.dll と regexp.dll がありました。これを dumpbin してみると、

>dumpbin /exports regexp.dll
Microsoft (R) COFF/PE Dumper Version 14.34.31937.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file C:\Apps\Python311\DLLs\regexp.dll

File Type: DLL

  Section contains the following exports for regexp.dll

    00000000 characteristics
    FFFFFFFF time date stamp
        0.00 version
           1 ordinal base
           1 number of functions
           1 number of names

    ordinal hint RVA      name

          1    0 00003160 sqlite3_regexp_init

  Summary

        2000 .data
        2000 .pdata
        A000 .rdata
        1000 .reloc
       10000 .text
        1000 _RDATA
となっているので、このDLLを読み込んでやればきっといいんでしょうね。
検索してみたら、Run-Time Loadable Extensions というページになにか書いてありました。が、いろいろ書いてあるんですが、じゃあどうすればいいの?がよくわかりません。

An SQLite extension is a shared library or DLL. To load it, you need to supply SQLite with the name of the file containing the shared library or DLL and an entry point to initialize the extension. In C code, this information is supplied using the sqlite3_load_extension() API. See the documentation on that routine for additional information.

Note that different operating systems use different filename suffixes for their shared libraries. Windows uses ".dll", Mac uses ".dylib", and most unixes other than mac use ".so". If you want to make your code portable, you can omit the suffix from the shared library filename and the appropriate suffix will be added automatically by the sqlite3_load_extension() interface.

There is also an SQL function that can be used to load extensions: load_extension(X,Y). It works just like the sqlite3_load_extension() C interface.

Both methods for loading an extension allow you to specify the name of an entry point for the extension. You can leave this argument blank - passing in a NULL pointer for the sqlite3_load_extension() C-language interface or omitting the second argument for the load_extension() SQL interface - and the extension loader logic will attempt to figure out the entry point on its own. It will first try the generic extension name "sqlite3_extension_init". If that does not work, it constructs a entry point using the template "sqlite3_X_init" where the X is replaced by the lowercase equivalent of every ASCII character in the filename after the last "/" and before the first following "." omitting the first three characters if they happen to be "lib". So, for example, if the filename is "/usr/lib/libmathfunc-4.8.so" the entry point name would be "sqlite3_mathfunc_init". Or if the filename is "./SpellFixExt.dll" then the entry point would be called "sqlite3_spellfixext_init".
For security reasons, extension loading is turned off by default. In order to use either the C-language or SQL extension loading functions, one must first enable extension loading using the sqlite3_db_config(db,SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION,1,NULL) C-language API in your application.
C言語から使うときには、sqlite3_load_extension() APIを使うといいよ、あとSQL関数の load_extension(X, Y) もあるよ、Xにはダイナミックライブラリ(WindowsではDLL)を指定すればいいよ、そうすればエントリポイントは勝手に実行されるよ、みたいなことが書いてあります。また、セキュリティ上の理由から拡張ローディングはデフォルトでは無効になってるので、sqlite3_db_config() でEnableしてやらないとだめだよ、とあります。
そのちょっとしたに、CLIではデフォルトでenableになってるよ、ともあります。残念ながらあまりいいドキュメントじゃないかも…。

ということなので、やってみました。
> sqlite3
SQLite version 3.40.0 2022-11-16 12:10:08
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> .dbconfig
          defensive off
            dqs_ddl on
            dqs_dml on
        enable_fkey off
        enable_qpsg off
     enable_trigger on
        enable_view on
     fts3_tokenizer off
 legacy_alter_table off
 legacy_file_format off
     load_extension on
   no_ckpt_on_close off
     reset_database off
        trigger_eqp off
     trusted_schema on
    writable_schema off
sqlite>
下から6番目に "load_extension on" とあります。有効化はされているようです。ところが、CLI から load_extension("regexp.dll") とかやってもエラーになるばかり。
うーん、うーん。

ここで Python のSQLite3 のドキュメントを見てみました。そしたらなんと、enable_load_extension(enabled, /)にありました。そこの注意書きには、sqlite3モジュールはデフォルトではローダブルエクステンションをサポートしてません、と書いてありますが…でもなぜか DLLs には regexp.dll があります
regexp.dllをどこからか持ってこないといけないので、Pythonに付属のSQLite 3.39.4のソースを拾ってきてVisual Studioでコンパイルしてみました。
コンパイルオプションはいろいろあるのですが、regexpはext/misc/regexpにあります。
何はともあれ試してみました。

> python
Python 3.11.1 (tags/v3.11.1:a7a450f, Dec  6 2022, 19:58:39) [MSC v.1934 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqlite3
>>> con=sqlite3.connect("videolist.db")
>>> cur=con.cursor()
>>> con.enable_load_extension(True)
>>> con.load_extension("c:/Apps/python311/DLLs/regexp.dll")
>>> cur.execute("SELECT * FROM videolist WHERE title REGEXP 'DUNE|DUNE'")
<sqlite3.Cursor object at 0x000001C72971A140>
>>> row = cur.fetchall()
え、なんかできてるし。 つまり、Python からならこれだけで SQLite3 の正規表現は使える、ということですね。 ついでに、さっき見たソースコードに正規表現ルールが書いてあったので引用しておきます。
The following regular expression syntax is supported:

    X*      zero or more occurrences of X
    X+      one or more occurrences of X
    X?      zero or one occurrences of X
    X{p,q}  between p and q occurrences of X
    (X)     match X
    X|Y     X or Y
    ^X      X occurring at the beginning of the string
    X$      X occurring at the end of the string
    .       Match any single character
    \c      Character c where c is one of \{}()[]|*+?.
    \c      C-language escapes for c in afnrtv.  ex: \t or \n
    \uXXXX  Where XXXX is exactly 4 hex digits, unicode value XXXX
    \xXX    Where XX is exactly 2 hex digits, unicode value XX
    [abc]   Any single character from the set abc
    [^abc]  Any single character not in the set abc
    [a-z]   Any single character in the range a-z
    [^a-z]  Any single character not in the range a-z
    \b      Word boundary
    \w      Word character.  [A-Za-z0-9_]
    \W      Non-word character
    \d      Digit
    \D      Non-digit
    \s      Whitespace character
    \S      Non-whitespace character

A nondeterministic finite automaton (NFA) is used for matching, so the
performance is bounded by O(N*M) where N is the size of the regular
expression and M is the size of the input string.  The matcher never
exhibits exponential behavior.  Note that the X{p,q} operator expands
to p copies of X following by q-p copies of X? and that the size of the
regular expression in the O(N*M) performance bound is computed after
this expansion.
非決定論的有限オートマトンなのでパフォーマンスは O(N*M) に制限される、とのことですが、とにかく動くことが大事なので見なかったことにします。 Python の re モジュールとはちょっと違うようですし、PCRE とも違いますが、ここまでわかればなんとかなりそうです。 実際のコードは、
import sqlite3
from sys import exec_prefix

    conn = sqlite3.connect(db_file)
    conn.enable_load_extension(True)
    conn.load_extension(exec_prefix + "/DLLs/regexp.dll")
    conn.row_factory = sqlite3.Row
    cur = conn.cursor()
みたいに使えばいいでしょう。

CDリッピングと音楽ファイル化。

一昔前はiRiverとかのデジタルオーディオプレイヤー、またはMP3プレイヤーとステレオイヤホンいうのが巷を席巻していましたが、今はみんなワイヤレスヘッドホンでスマホで、iTunesとかYouTubeとかAmazonミュージックとかのストリーム再生なんでしょうか。

自分の場合はCDを購入して聴くことが多いのですが、外出時には当然CDプレイヤーを持っていくことはないです。スマホのストレージに音楽ファイルを入れておいて、お気に入りのプレイヤーアプリで再生という使い方が多いです。

で、久しぶりにCDを買ったので、これまでのようにリッピングしようかと思い、新しいメインPCに定番で使っていたCDexをインストールしようとNASのフォルダを開いたところ、Windowsセキュリティが反応してPUABundler:Win32/FusionCoreが入ってるから検疫する?と聞いてきました。

このFusionCoreはいわゆるマルウェアやアドウェアというタイプで、不要な広告を表示するもの。無害といえば無害だけど、ユーザの許可なくインストールされて動作するという点ではお行儀の悪いソフトです。

CDex自体は2020年以降のアップデートはされていないようです。なので他にいいのがないかどうかを探してみることにしました。

目的はCDから音楽データを吸い出してスマホで再生可能な音楽ファイルに変換すること。変換は最近使っているFDK_AACが使えればいいな、という程度です。それからもうひとつ重要なのが、吸い出しの際にCDDBからアーティストや曲名を拾ってこれること。これがないとFile001.wavなどというものになってしまい、ファイル名からなんの曲なのかがわからなくなってしまいます。

ちなみにこれまで長い間利用していたCDデータベースの freedb.org は2020年3月末で終了していたのに今さら気づきました。ということは2年以上も音楽CDを購入していなかったってことかしら。

その代わりではないですが、MusicBrainzという音楽Wikipediaみたいなサービスがあり、そちらを使うことでfreedb.orgと同じことができるようです。


最初はWindows用で探したら、Monkey's Audioというものが見つかりました。が、どうやらこれ単体ではCDからのリッピングはできないようです。リッピングツールは別に用意して、WAV形式で吸い出したものをMonkeysAudioで圧縮するという手順になるのですが、リッピングツールとしては非常に評価の高いExact Audio Copyが使えます。音楽CDはデータCDのようなエラー訂正の仕組みはないのですが、音楽データを正確にリッピングすることができるらしい、です。

Exact Audio CopyはWAVデータとして保存することもできますが、同時にエンコードもできるようです。デフォルトでは以下のような外部エンコーダに対応しているようです。



外部エンコーダなので、別途エンコーダ自体を用意しないといけません。以前にFFmpeg 5.0をコンパイルしてみる。でFDK_AACのエンコーダをビルドしているのでたぶんこれが使えるとは思いますが、もうちょっと安直にできないかな、と探してみました。

最後に見つけたのがfre:acです。
fre:ac is a free audio converter and CD ripper with support for various popular formats and encoders.
ということで、いろんなフォーマットやエンコーダをサポートしています。CDDBもGnuDbという音楽データベースに対応しているようです。
Gnudb.org a new home for the freedb.org database to make sure it stays free.

 freedb.orgのデータベースを移行したんでしょうか。GNUプロジェクトとの直接の関係はないように見受けられますが、Wikipediaには次のように書いてあります。

2020年3月31日をもってサービス終了することが告知され、全てのサービスが終了し、gnudb.orgへ自動的に転送されるようになっている。

どうやらfreedb.orgへのアクセスはgnudb.orgに転送されるようです。

それはさておき、fre:acはデフォルトで以下のようなエンコーダをサポートしています。


FDK-AACが入ってますね。ラッキーです。ワンストップでリッピングからエンコードまででき、かつ <アーティスト名>/<>/nn-曲名.m4a のように出力ファイルの場所と名前を指定できるので、これでいこうと思います。

そのうち、倉庫に保管してるCDもエンコードし直すかな。


ちなみにちなみに、Linuxではどうかと思って検索してみたら、abcdeというのが見つかって、このabcdeはshスクリプトでツール類を適宜起動してリッピングからエンコードまでやってくるようなんですが、WSL2でのArchLinuxにcdparanoia入れてabcdeで動くか、と思ったらそもそもcdparanoia自体が動きませんでした。
正確に言うと、cdparanoiaは起動時に /dev/cdrom や /dev/hd0a などのブロックデバイスを探しにいくのですが、WSL2では親側のCDドライブ(DVDでもBDでも)をマウントするには

mount -t drvfs q: /mnt/q

みたいにマウントして参照する以外はまだできていないようで、この時点でアウトっぽいです。

NVR510に切り替えてみた。

9月3日に、ルーターをこれまで使っていた NEC Aterm WR8700N から YAMAHA NVR510 に置き換えました。この際だから ONU も NVR510 にセットできる小型 ONU に変更しようかと思いつつ、今のところはそのまま。

IPv6のPPPoEとIPv4のPPPoEをそれぞれセッションとして登録し、これ自体はちゃんと動いたのですが、どうもスタティックルーティングの Flets サービス情報サイトへの接続がうまくいかないのでどうしたもんかと思いつつ。

ZOOT NATIVE IPv4固定IP1個サービスが2ヶ月無料、月額基本料金2,200円(税込)ということだったので、どうせ IPv6 IPoE に切り替えるつもりだったこともあり、9月4日に申し込みしました。

IPoEを申し込むには、自分が使用している回線のお客様ID(CAFxxxxみたいな番号)とアクセスキーが必要になります。IPoEでは、ユーザ認証は網側にこの情報を登録するので、PPPoE とは異なりルータの設定にIDとパスワードは不要になります。

実はこの ID はNTT回線開通時に送られてくる契約書に書かれているのですが、保管してるのは確かなんだけど見つからなかったので116に電話して契約書の再発行をしてもらいました。そのため ZOOT NATIVE 自体の申込みが9月にずれこんだのでした。

それはともかく、ZOOT NATIVE IPv4固定IP1個サービスに申し込むと1時間ほどで登録完了メールが送られてきます。そこには、ルーターの設定に必要な契約サービス情報の

  • 固定IPトンネル終端装置IPv6アドレス
  • インタフェースID
  • グローバル固定IPv4アドレス
  • アップデートサーバーユーザー名
  • アップデートサーバーパスワード
  • アップデートサーバーURL

が記載されていて、これを NVR510 の簡単設定で登録してやればすぐに繋がりました。IPフィルタ設定やDNSサーバなどもそのままで、サービス情報サイト(v6)にもそのまま繋がりました。

また、ZOOTのサーバー構築支援ツールのページから自分のIPアドレスにpingを飛ばすと、ちゃんと応答があります。

固定IPが確認できたので、gonbeiのDNSサーバーに新しいIPを登録し直してとりあえずの作業は完了。一通り設定が終わったので、1週間くらい様子を見て、ZOOT NEXTを解約しようと思います。

自分メモ: ManjaroLinux を pacman -Syu したらいろいろ変わってた点。

 たぶん数カ月ぶりくらいになると思いますが、NVR510 を導入して ZOOT NEXT から ZOOT native に切り替えたのを機に、またサーバ環境を構築しようかと ManjaroLinux を pacman -Syu してみましたが、いろいろ変わってそうなので備忘録。

locale.conf, locale.gen:
locale.conf.pacsaveとして保存されました、とメッセージが出たけど見当たらないので気にしない。locale.genはいくつか新しいlocaleが追加されてました。

/etc/security/limits.d/10-gcr.conf:
10-gcr.conf.pacsaveとして保存されました、と出ていたので、新しいと思われる方を残しておきました。

gnome-keyring:
Symlinkを作ってました。
Created symlink /etc/systemd/user/sockets.target.wants/gnome-keyring-daemon.socket → /usr/lib/systemd/user/gnome-keyring-daemon.socket.

kea:
だいぶ前から出ているメッセージなのでメモだけ。以前のバージョンは2.0、今回のバージョンは2.0.3なので非該当ということで。
## WARNING!##
Upgrading from Kea version <1.6 to version >= 1.6 requires special attention
Please refer to the following web page for details:
[Upgrading to Kea 1.6](https://kb.isc.org/docs/en/upgrading-to-kea-16)
Notable changes include:
 - Files in /var/kea have moved to (/var)/run/kea
 - State Info: now in /usr/lib/kea
 - Hooks: /usr/lib/hooks has moved to /usr/lib/kea/hooks
 - Admin commands lease-{init,version,upgrade} have been renamed
   to db-{init,version,upgrade}
 - Logger configuration changed scope thus a manual configuration
   file intervention is needed)

lightdm.conf:
/etc/lightdm/lightdm.conf.pacnetとしてインストールされました、というメッセージが出たので、内容を確認してマージ。

mkinitcpio.conf:
/etc/mkinitcpio.conf.pacnew としてインストールされました、というメッセージが出たので、内容を確認してマージ。

mariadb:
dbをアップグレードしてね、と出ていたのでアップグレード。
"systemctl restart mariadb.service && mariadb-upgrade -u root -p"

sudo:
/etc/sudoers.pacnew としてインストールされました、と出ていたので内容を確認してマージ。

unbound:
/etc/unbound/unbound.conf.pacnew としてインストールされました、と出ていたので内容を確認。IPv6関係を見直し。

perl:
5.34のmoduleはシステムでは使ってないけど依存関係があったので削除されてないから、
pacman -Qqo '/usr/lib/perl5/5.34'
で調べて対応してちょうだい、と言われたので調べてみたら、x2goserverが呼び出している様子。x2goserverは2021/5/24にビルドされた4.1.0.3-10が最新のようで、perlモジュールをいくつか使用していて、たぶんperlモジュールのバージョンを上げても大丈夫だろうとは思うけど、念のためそのまま残すことに。

ざっと以上です。

NVR510を買ってみた。

 どうも会社PC(VPN)の通信速度が遅いので、プロバイダが悪いのかルータが悪いのかそれともIPv6にすれば速くなるのか(IPv4 over IPv6)、とりあえず参考までにPCをONUに直結して東日本のフレッツサービス情報サイトに繋いでみました。

これはフレッツ網内の速度なので、プロバイダを通した速度とは異なるとは思いますが、まずは倍以上速くなりそうという感触は得られます。


うちはプロバイダはインターリンクで、ZOOT native 固定IP1個というタイプになります。

実はこれまでAterm WR8700nといういささか古いモデルをルータとして使っていましたが、これだとIPoEとかIPIPとかはできないんですよね。なので、ZOOTがIPv6を通してくれるようになったのに恩恵にれていませんでした。

ということで一念発起、YAMAHA NVR510を注文してしまいました。

ちょっと光回線(フレッツNEXTギガファミリー)の契約情報が、これまでサービス情報サイトにちゃんと接続できていなかったのでクラブ登録もできず、NTTにお願いして開通書類の再発行をしてもらっているので、本格的に繋げられるのはもう少し先になりそうです。

スタートアップに登録されているものを削除する。

 CTRL+Shift+ESC でタスクマネージャーを起動してスタートアップのタブを開くと、結構たくさん登録されていて、ここで有効/無効を切り替えてあげればスタートアップ時に実行されることはなくなります。

なくなりますが、この項目をこのタブから削除することはできません。


たとえばターミナルとターミナルプレビューは、現在プレビューを使っていて、以前のターミナルは使っていません。同じような項目が並んでいるのは気持ち悪い。

その他にもシュナイダーのStartup Notification Moduleが2つあったり、ScanSnap Homeが2つあったり。

この項目の実体は複数の方法で登録されていて、一箇所から管理できません。なので個別に見ていく必要があります。

ショートカットのもの

  • C:\Users\%USERNAME%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
  • C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp
レジストリのもの

  • コンピューター\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
  • コンピューター\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

  • コンピューター\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run
ここらへんから削除してしまえば、スタートアップタブから項目が削除できます。

SWDなら3線でいいとはいうものの。

 安価で優秀なデバッグプローブはないかしら、と探したら、 Raspberry Pi Debug Probe というのがあったんですが、これは3線がにゅるんと出てるだけです。 もちろんSWDなら3線を繋げばいいのではありますが、汎用的に考えるなら5x2のリボンケーブルコネクタが欲し...