Archive for the ‘Linux’ Category

前の投稿を書いている時に思い付いた、「電子アナデジボリューム」(仮)を試してみた。なかなか大変だったうえに結果はイマイチだったwが、とりあえず考えたことができたので、満足して(そそくさとw)元に戻した。

この方式は昔のアナログシンセ(のVCA)のように音量を制御するので、上記の仮称にした。再生する音の音量調整は完全にデジタル(要するに掛け算)なのだが、その調整量はアナログ信号(電圧)で制御している。以下に構成図(概略)を書く。

                                        PC  | 外
制御信号発生 → PCのアナログ出力 | → 音量調整用ボリューム
ローパスフィルタ ← 全波整流 ← PCのアナログ入力 | ←+
             ↓ 音量調整用ミキサー
            音量調整入力
音楽再生音 → 再生入力 → DAC | → オーディオアンプ → スピーカー

備考

  • PCのオーディオ入出力が直流を扱えないため、音量の制御信号は正弦波とした。なお、周波数は100Hzにした(制御用に使ったPCのオンボードのオーディオインタフェースは超低域の特性が悪いようで、35Hz辺りのように余り低いと安定しないようだったため)。また、なるべく制御信号が音楽に混じらないように、出力レベルを下げた。
  • 音量調整用のミキサーは電圧で音量が制御可能な、Non Mixerを使った。

なお、この稿では「ボリューム」は物理的なボリューム(可変抵抗器)の部品を、「音量」は音楽を再生しようとする音量(の設定値)を指す。どちらも元は同じ意味の言葉ではあるが・・・

以下に関連する画像を載せる。

試行錯誤しながら心配したのだが、アナログ信号で音量を制御するために、音量の設定値が今一つ安定しなかった。正確には、アナログだから悪いのでなく、制御信号が交流(音)で、その振幅を(AMラジオのように処理して)調整量にするので、「ちょっとやってみた」程度ではなかなか安定しなかった

そして、その音量設定値の変動のせいかは不明だが、どうも再生音が悪かった(気のせいかも知れないが、今までの経験では大抵当たっている)。音量の変動以外の良くない要素として、音量調整はデジタルではあるが、アンプに入れる前に小さくしてしまうのが余り得策でないように思う。

それから、ボリュームを動かす量と音量の関係が今一つだった(逆に、普通にアナログでボリュームを使う方が自然で良かった)。この辺りは制御信号のオフセットや傾きや曲線(対数?)を調整するといいのだが、(ガチのデジタル信号処理用でない)音楽用の処理モジュールには丁度いいものは見当たらず、調整は容易ではなかった。

なお、周波数を測定するモジュールもあって、周波数で音量を調整する(FMラジオ方式)こともできそうだったのだが、ボリュームで周波数を変えるのは容易でない(そもそも、信号発信器なんて持ってない)うえに安定させるのは難しそうなので止めた。

今日はアナログ処理の難しさ・面倒さを体感した。でも、おもしろかった^^

 

(6/17 11:22 わずかに加筆・修正、リンクを追加; 18:56 ちょっと修正)

  •   1
  •   0

病院(主に医院)の待合室の本棚には、大抵、興味をそそらない、院長や奥さんなどの趣味であろう、週刊誌(例: ファッショナブルな女性誌、外車の雑誌)や古い本や漫画(例: 「サラリーマン金太郎」、「ドラえもん」)しかないw 健康診断で行った医院もそうだったのだが、暇なので題を眺めていたら、無意識のうちに(パターン認識のような感じ)「ん?」と思った(何となく違和感を感じた)本があったので、視線を戻した。日に焼けて背の文字が薄くなっていたのだが、良く見たら、題はなんと、

Ubuntu Linux入門キット 10.04対応

だったwww Ubuntu 10は2010年頃のようだから、一時流行っ(てすぐ消え)た頃(2000年代?)ではなさそうだ。院長に何か考えがあって試し(てすぐ諦め)たのだろうか? 雰囲気的に何となくそんな気もするが、単に、患者とかが持って来たのかも知れない。

もし院長だったら、歳が近いので、そういう話で盛り上がるのもおもしろそうだが、患者が多くて忙しいようだし、僕は自分から持ち掛ける性格ではないので、なかなか機会はなさそうだ。まあ、「仕事は何しているんですか」とか聞かれたら、話が繋がるかも知れないな。

  •   0
  •   2

先日、暫定対処したと思っていた本サーバが、今朝またOSのパニックで落ちていた。

ログが壊れたために直接の原因は断定できないが、今まで同様に、パッケージlibjson-c2の更新が切っ掛けではないかと推測した。それで、(前回はしなかったのだが、)Ubuntuのフォーラムに書かれていた対処(postinstというスクリプトを削除してlibjson-c2を最新版に更新する)をしてみたのだが、当然といえば当然ながら、やっぱり落ちた。更にそのスレッドを参考にして調べてみたら、libjson-c2の更新後にpostinst内で行われる、telinit uとかいう(初めて見る)コマンドを実行すると落ちることが分かった。

これに関連して謎だったのだが、僕のPCも同じUbuntuの系統(16 LTS)だけどlibjson-c2を更新しても落ちなかったのは、どうしてかtelinit uを実行しないからのようだ。その原因は、良く分からないのだが、僕のPCではupstartのセッションがある(PCではinitctl list-sessionsでセッションが出るが、サーバでは出ない)かららしい。それは僕のPCがデスクトップだからのようだ。

結局、Ubuntu 16 LTSのtelinitに問題があるようで、それは2014年に報告されたまま直っていないようだ。その後、何度かメジャーバージョンアップがあり、今回の問題に関係する仕組み(例: upstart)も大幅に変わったらしいので、放置・忘れられているのだろう。確かに古いけど、サポート期間内なのだから対応して欲しいとは思うが、まあ、あっちもパワーは有限だから仕方ない(それに、無料で使わせてもらっている)。

それで、至急OSのバージョンアップをすることが必要なのは よーく分かったのだが、そうは言ってもなかなか大変で、やろうと思ってもコマンド一発とかですぐにできるものではないので、今は再び暫定対処することにした。具体的には、パッケージの更新後に(postinstスクリプトに)telinit uを実行するように書かれていても実行されないようにした。

まず、libjson-c2のpostinstスクリプトを変更してtelinit uを実行しないようにしてみたが、libjson-c2を更新するとそのスクリプトも上書きされるので駄目だった。次に、telinitコマンドを無効にすることを考えたが、これは他からも使われる(特に、システムの起動時にOSのランレベル(実行モード)を変えるために使われるそうなのでとても重要だ)ので、それ自体をなくすことはできないので、引数に"u"が指定された時は記録だけして何もしないようなスクリプト("fake-telinit.sh")を作り、それにすげ替えた。

試してみたら、見事に起動しなくなったwww

寝ぼけていたのか、telinitをfake-telinit.shにすげ替える設定(sym-link)に誤りがあり、起動時にランレベルが変えられなくなり、それ以上進まず、何もできなくなってしまった。まさに「にっちもさっちも行かなく」なって、観念して再インストールの手順を調べたら、使っているVPS(仮想サーバ)には「アップロードしたISOファイルからインストールする」という大変有能な機能があったので、それでUbuntuのインストーラ−を起動し、OSの修復モード(Rescue mode, Windowsのセーフモードのようなもの)で起動し、設定の誤りを修正して、どうにか再インストールせずに起動するようになった。以下はVPSの仮想コンソールの画面のキャプチャである。仮想コンソール(ブラウザで動く)がそれなりに使えたのも、大変助かった。。。

落ちたのが分かってから直るまでに2時間くらい掛かって、心身共に大変疲れて今日の予定が吹っ飛んだ。

OS更新の代わりの対策は、今のサーバのOSでも動く新しいtelinitを探してインストールすることだが、探すのが大変だし(あるかどうかも不明)確認も面倒なので、保留している。

なお、パッケージ更新後にtelinit uの実行が必要なのにされないままだと、更新したパッケージが反映されないので、メールで通知するようにした。それが来たら手で再起動すれば良い(もちろん、理論的には自動で再起動するようにもできるが、とんでもないことになる場合があるので、しないw)。

僕のデスクトップPCは自動再起動しない設定で似たようなことをやっているから、結局、サーバの更新後に自動再起動する設定を止めればうまく行くのかも知れないが、今回は再起動している訳ではなく、telinit uで済ませようとしているので駄目な気もする。

最後に、今まで問題が起こらなかったことが謎だが、たまたまtelinit uを行うパッケージがなかったからかも知れない。あとは、プロバイダのメンテの結果、VPSの物理マシンが変わったためにtelinit uの挙動が変わったのかも知れない。

もし後者が原因なら、他のクラウド環境(例: AWS)でも現象が起こっているようなので、それ用に対処されたパッケージを探せば(あるのなら)直りそうだが、通常のPCでも起こっているようだから、仮想環境とは関係なく、ハード依存なのかも知れない。すると、やっぱり、「新しいtelinit」が要ることになる。

まあ、謎は多いようだ・・・

  •   1
  •   0

まだ「概ね」で いろいろ問題はあるけど、以下のように、僕が欲しかった機能はすべて実現した。

  • 指定した期間内または前回のバックアップ後に更新されたノートを指定ディレクトリにバックアップ(ダウンロードと保存)する。
  • ノートの本体(テキスト)だけでなく、添付された画像など(リソース)もバックアップする。
    • 純正Evernoteアプリの全ノートのエクスポートと違い、ノートごとに分けてバックアップする。また、本体と各リソースも別のファイルにしている。(その方が扱いやすいと考えたため。)
  • ノートの最新版がバックアップ済みの場合は、ダウンロードしない。
  • バックアップしたノートは、webブラウザでプレビュー可能。
    • トップページにはノート一覧(ノートのタイトル、更新日時、ノートブック、GUID)が表示され、タイトルをクリックするとプレビューされる。プレビューは、Web版Evernoteにまあまあ近づけた(というか、見栄えはまったく凝ってない(テキトーにやったらそれなりに見えた)。: 例に挙げたノートも目をひかないw)。

(5/23 20:19) その後、プレビュープログラムを改良し、トップページは「(バックアップした)Evernoteのブラウザ」のようになって来た。以下のような機能を追加したほか、見栄えを少し良くした。やっぱり、PHPだと開発効率が10倍はいい感じだし、やる気も出るw

    • フィルタリング機能: 更新年月、作成年月、バックアップ年月、ノートブック名で表示するノートを絞り込める。また、左の各フィールドに対して正規表現でフィルタリングできる。
    • ソート機能: タイトル、更新日時、作成日時、バックアップ日時、ノートブック名でソートできる。ソートの昇順・降順は、フィールド名を押すことで反転する。ソートに使っているフィールドは太字になり、ソート順は▲(昇順)/▼(降順)で示される。
    • 編集補助機能: トップページまたはプレビューページのノート名横の"Edit"を押すと、web版Evernoteでノートの編集ができる。 (あとから思い付いて追加したので、キャプチャ画像にはない。)

改良したトップページ (ノートブック名でフィルタリングした状態)

これくらいできると、僕には、ノートを探すことなどに関してはweb版Evernoteより使いやすい。Web版Evernoteはマウスの加減で画面がちょろちょろ動くのが鬱陶しいし、ノートが多いと下の方がなかなか出て来なくて(しかも、下を出すと上を出すのが遅い・・・)不便なのだ。技術的には高度だろうけど、本当に使いやすいのかと思う。

構想や調査・準備(・他のこと)に時間が掛かったが、ここまでの実装は5日くらいでできた(または、5日も掛かった)。気付くと寝食が犠牲になっていて、なかなかハードだったw

問題や不満な点や残件はいろいろある。

  • 多くのノートをバックアップしようとすると、Evernote APIのrate limit(レート制限: APIを使い過ぎるとエラーになってしまう)に掛かって、しばらく(例: 30分-1時間)使えなくなる。一旦制限に掛かると、制限期間が終わってもすぐに駄目になることが多く、かなり間隔を空ける必要がありそう。(← プログラムのバグのため、無限にダウンロードしていたせいだった。) → 僕の全ノートのバックアップは時間的に困難かも知れない。 → (5/22 16:02) 調整やデバッグをしたら調子が良くなって、1年分を1時間くらい(レート制限解除の待ち時間を含む。正味の時間はもっと短い)でダウンロードできるようになった。 → (5/22 19:14) 無事、全ノート(2011年から今年まで)がバックアップできた。なお、(多過ぎて)過不足や内容の確認はできない模様w (バックアップのサイズ: 562MB, ノート数: 725)
    • あるアプリを初めて使う場合は、使い始めてから24時間は無制限("Initial Sync Boost")なのだが、当然ながら開発中に終わってしまった。。。
    • 開発用認証キーを取得すると、それで「最初の24時間」が使えて良さそうだが、今は配布が停止中。
      • 開発用キーとAPIのキーは別なので、後者を取得すればいいようだが、ちょっと躊躇している。
    • 他のサービスのように、APIの推奨実行間隔や制限に掛かる条件を明記してくれたり、APIの戻り値にレート制限に掛かりそうな情報(例: 「あとどのくらいで制限になる」)を出してくれるとありがたいのだが、そうではないようだ。その点ではSpotifyはまともだ。
  • そもそも、Evernote APIは無駄に凝っている。複数プログラミング言語対応などを目指したのか、Thriftとかいうのを使っているが、複雑で面倒でどうしようもない。センスが悪い。最高でなくていいので、もっと「普通」の、楽なやり方にすればいいのに。この点でもSpotifyは随分良かった。
  • Evernote APIでは、ノートのリソース(画像など)だけの追加や置き換えができず、そうしたい時には、ノート全体(すべてのリソースを含む)を再びアップロードし直すことになるようで、スマフォでは大きいノートの編集が重くなるのも分かる気がした。通信データ量も増えてしまうから、とてもイマイチな仕様だ。 (5/25 16:40)
  • バックアップ期間の日時指定がUTCなので、今一つ不便。(単に変換をサボっているだけ)
  • 元のプログラム(clinote)の内部構造が大変イマイチで、すごく保守性が悪い。
    • 同じ名前や似た名前のファイルが違うディレクトリに何個もあって、今自分がどれを見ているのか分からなくなる。
    • 関数名や型の名前も同様に同名や似たような名前のものが多く、それらの間で頻繁に行き来するので、何がどこにあるのか把握できない。その割には、かなり細かいこともやっていて、本人が間違えないのが不思議。逆に、大雑把なところも多く、バランスが悪い気がする。
    • 作者は僕とは違う感性のようだ。GMBもちょっと似た雰囲気だった。USの人とは違う気がするので、どちらもヨーロッパの人?
    • することは大体分かったので、いつかはPHPで0から書き直したい! (いつになることやら・・・)
  • GO言語もイマイチ。
    • やっぱり、コンパイラ・静的な言語は不便だ。
      • 例えば、変数が静的なので、配列への要素の追加・削除が普通にできない。昔のCでの苦労を思い出す・・・ そういう処理をしようとして、「あ・・・」と気が重くなって、手抜きをする。
      • 変数の型にも厳格で、実体が同じだってエラーにするからいちいち面倒だ。
    • 変態的かつ不便なだけで、全然メリットが感じられない。
      • ;だの{}だの()を省けるようにしたって、そういうのは本質じゃないから全然良くない。逆に、様式が多いのは戸惑いを生じるから面倒だ。
      • 日時のフォーマットの指定方法なんて、アフォとしか思えない。これがGoogleの乗り?
      • あと、今時ポインタなんて要らないんだよ、クソジジイ!!!
        • ↑ 変数は「参照している間はなくならない」そうで、Cでのスタックとヒープの違いがないとのこと。だから、関数内のローカル変数のアドレスを呼び側に渡しても何も問題ないそうで、すごく気持ち悪い。その点でも、やっぱりポインタやアドレスをなくせば良かったのにと思う。 (5/25 16:40)
      • 重複した機能のライブラリがあって(例: osとioutilのファイルアクセス)、新しい言語なのに既にごちゃついている感じ。
    • この点でも、いつかはPHPで書き直したい!
  • まだリストア(アップロード)機能を作っていないので、本当にリストアできるかが不明(プレビューできているので、おそらく大丈夫とは思うが・・・)。最悪でも、本文とリソースはバックアップできているから何とかなるはず。
    • → (5/25 16:40) とりあえずできた。バックアッププログラムを作る時には気付かなかったのだが、ノートをアップロードする時にはリソースのタイプ(MIME)やハッシュ値(MD5)や、画像の場合にはサイズ(幅・高さ)も要るので、面倒だったがGoのライブラリで認識・生成した。
    • 今回も、Goの変態さに気付いてしまった(上に書いた)。

次に、細かい機能や実装などについてのメモを以下に書く。

  • コマンドライン版のEvernoteクライアントclinoteを改造した本体と、それを呼ぶシェルスクリプト(en_backup.sh)、バックアップしたノートのプレビューを行うCGIプログラム(enb_viewer.php)で構成した。
  • clinoteの改造概要
    • ノート一覧をCSV形式で出せるようにした。CSV形式の他に、元々の形式で出る余計な区切り(線)を出さないようにすることができるようにした。
      • 元々の表示は昔のDOSやPC98のプログラムみたいで、使い勝手も趣味もとても悪い。
    • ノート本体だけでなくリソースもダウンロード・保存できるようにした。保存時にノートを変更せずに、Evernoteからダウンロードしたままの形式(ENML形式)で保存することもできるようにした。
    • ノート情報(タイトル、更新日時、作成日時、ノートブック、GUID)を情報ファイルに記録するようにした。
      • バックアップ時に、これに記録された更新日時とEvernoteから取得した更新日時を比較して、再度のダウンロードや上書きをしないようにしている。
      • プレビュー時も、この情報を使ってタイトルなどを表示している。
    • リソースのファイル名はリソースのハッシュ値(Evernoteが計算してノート本体から参照される値)にしたので、変更が簡単に検出できる(はず)。
      • (5/22 13:25) その後、ノート内の各リソースが更新されたかを調べると、リソース(例: 画像)数の多いノートでAPIの実行数が増えてレート制限が起こりやすくなることが分かった。Evernoteはデータ転送量よりAPIの実行の方が重い(コストが高い)と考えているようだ。それも分かるが、何となく釈然としなかった(僕は転送量を減らそうとして失敗した)。 → 結局、ノートが更新されていたら、各リソースの更新はチェックせず、ノートと一緒に全部ダウンロードするようにした。
        • APIの実行数を最小にするという点では、ノート本体の更新チェックもせず、とにかく全部ダウンロードするのがいいが、さすがにかなり遅くなるので止めた。
    • ノート(本体、リソース、ノート情報ファイル)はノート本体のGUIDの名前を持つディレクトリに保存するようにした。
    • APIレート制限の状態を簡単に知ることができるように、同期状態(GetSyncState)を表示するサブコマンド(sync-state)を追加した。
      • clinoteは、レート制限エラーが起こっても他と同様のエラーにするだけで、制限が解除されるまで待つべき時間(rateLimitDuration)が分からない。
      • 一方、レート制限エラーはさまざまなところ(API呼び出し)で起こり得るので、そのすべてに表示処理を追加することは容易でない。GOの機能でできるのかも知れないが、慣れていないのとプログラムが複雑で、僕には無理だった。
      • そのため、追加したsync-stateサブコマンドではレート制限エラーでの待つべき時間をエラーメッセージに表示するようにした。そして、プログラム実行時にレート制限エラーが起こったあとでsync-stateを実行すれば、そこでもレート制限エラーが起こるはずなので、そのエラーメッセージからレート制限が解除されるまでに待つべき時間を抽出できるようにした。
    • バックアップしたノートのリストア用に、clinoteでノートを新規作成するサブコマンド(note new)にノートのアップロードを行うオプションを追加した。 (5/25 16:40)
      • そのオプションに、アップロードするノートとリソースファイルの格納されたディレクトリを指定する。
      • リソースのアップロード時に、タイプ(MIME)やハッシュ値(MD5)や、画像の場合にはサイズ(幅・高さ)が要るので、リソースファイルから生成するようにした。
      • ノートのタイトルを指定しない場合には、ノートのディレクトリに(バックアップ時に作成された)ノート情報ファイルがあれば、そこに記録されたタイトルが使用される。
      • ただし、既存のノート(同名で存在する可能性がある)と容易に区別できるように、指定しない限り、アップロード専用のノートブックに入れ、タイトルにアップロードしたという識別記号を前置するようにした。
  • バックアップ実行用スクリプト(en_backup.sh)の概要
    • バックアップ対象期間、保存ディレクトリ、APIレート制限時の自動リトライなどが指定可能
      • うまい方法がなかったので、レート制限エラーかどうかとレート制限が解除されるまでの時間は、前述のようにログ(clinoteの出力)から抽出している。
    • 最後にバックアップした日時をファイルに保存しておき、次回以降にバックアップ対象期間を指定しない場合には、前回以降に更新されたノートをバックアップすることが可能。 → crontabに書いておいて、定期的に自動バックアップすることも簡単にできる。
    • バックアップ期間の指定は検索条件(例: "updated:20200501T000000Z -updated:20200520T000000Z")としてclinoteに渡し、Evernote APIで行っている。
  • Webプレビュープログラム(enb_viewer.php)の概要
    • バックアップしたノートをHTMLに変換して表示する。
      • 変換といっても、リソース(画像など)が表示できるようにタグを置換している程度。以下に主な規則を書く。
        • プレビューページの先頭に<!DOCTYPE html><html>を入れる。
        • ENML → HTML簡易変換 (PHPの正規表現(PREG))
          • <!DOCTYPE(\s)en-note\s[^>]+> → 削除
          • <(/)?en-note> → 削除
          • <en-media\s+'<img '
          • hash="([^"]+)"'src="'.$img_dir.'$1"' (注: $img_dirはノートのディレクトリ)
        • Evernote内リンクの変換
          • "https://www.evernote.com/shard/([^/]+/){3}([^/^\?]+)(\?[^"]+)?" + → (そのノートのGUID($2)ををプレビュープログラムに指定して表示させる)
          • evernote:///view/[^/]+/[^/]+/([^/]+)(/[^"]+)? → (そのノートのGUID($1)をプレビュープログラムに指定して表示させる): これはNixnote2独自のものかも知れない。
        • プレビューページの最後に</html>を入れる。
    • まだCSSなどは使用していないので(多分、今後もやらない)、とりあえず見える程度のもの。

最後にその他の情報などを書く。

  • Web版Evernoteでノートを変更してから数分(2-3分)経たないと、APIにその更新が反映されない。
    • ノートをバックアップする時、編集中のものをバックアップするのを防ぐため、更新後少し経ったものを対象にしようと思って居たので、この仕様は偶然にも都合がいい。
  • これを作っていて、今までに試したEverenote互換アプリで、最初の同期が終わらず、全然使い始められないないものがあった理由が分かった。ノートが多過ぎて、最初の同期中にレート制限が掛かり、待ちと制限の繰り返しになっていたのではないか。
    • それならそのように表示すればいいと思うが、なぜかそういうアプリは少ない。出てもすぐに消えてしまったり、意味不明なエラーを出して、今どうなっているのかが分からないものが多い。
  • 想像だが、NixNote2は余計なことをし過ぎていて(どういう訳か、Evernoteの普通のやり方から外れて独自のことをしている感じ。Evernoteのクライアントなのに・・・)、ノートが編集できなくなったり、同期が失敗したり、スマフォで開く時にノートが重くなったり、フォーマットが乱れたり(純正アプリと違うことが多い)するのではないかと思う。 ← 今読み返すと、全く使い物にならない。
  • バックアップしたノートのサイズを比べてみたら、僕のが約560MBに対して、純正アプリのは約900MB(ただし、昔のもの)と約2倍だった※。一方、NixNote2のは約3.2GBと馬鹿のように大きい。その点でも糞アプリだったようだ。 (5/23 6:32)
    • ※僕のは保存するデータが何か欠けているのかも知れない。あるいは、画像などを文字にエンコードせずにそのまま保存しているから小さいのかも知れない。

 

余談

バックアップしたノートのビューアをPHPで作ったら、もう、水を得た魚のようにスラっと気持ち良く作れて、サクッと動いた。いくらでも機能を追加できる気分になれるのは、すごくいいことだ。どっかのモグラや蛇や真珠もどき(駱駝・玉ねぎ)とは全然違うw もちろん、赤い宝石なんてお呼びでないwww (5/22 19:28, 22:14)

 

(5/23 5:48, 6:32 加筆; 8:37 最初の文章が消えていたので復元した。若干加筆。; 5/23 20:19, 21:00 Webプレビュープログラムの機能追加を追記; 5/25 16:40 アップロードを作った件と、Evernote APIとGoのおかしさを追記)

  •   0
  •   1

先日書いた謎の二つ目、「ブログサーバーが突然落ちた・・・」も解けた感じだ。

書いてからは落ちていなかったのだが、今日、PHPを更新しようとしたら、以下のようなエラーになり、メッセージに従ってdpkgコマンドを実行したら、パニックで落ちた(「え? 言うとおりにやったんですが・・・」って感じだったw)。

E: dpkg was interrupted, you must manually run 'sudo dpkg --configure -a' to correct the problem.

それで、OSのエラーの出るサーバの仮想コンソールを見ながら再度同じコマンドを実行したら、

Setting up libjson-c2:amd64 (0.11-4ubuntu2.1)

と出て落ちた。どうも、libjson-c2というパッケージの更新が駄目なようだ。それで、試しにパッケージ情報の更新(apt-get update)をしてみたら別のエラーになった。検索すると、dpkgやaptのロックファイルを削除すればいいとのことだったが、それでもエラーになった。他のロックファイルを探して削除したら、パッケージの更新はできたが、libjson-c2の再インストールはPHPと同様のエラーになり、書かれているとおりにdpkgを実行したら、やっぱりパニックで落ちた。

どうもOS自体がおかしいようなので、調べてみることにした。

まずは、dpkg -Vというコマンド(今日知った)で各パッケージの状態を見てみたら、やっぱり、libjson-c2とlibjson0の状態が駄目っぽかった。

$ dpkg -V
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
:
iF libjson-c2:amd64 0.11-4ubuntu2.1 amd64 JSON manipulation library - shared library
iF libjson-c2:i386 0.11-4ubuntu2.1 i386 JSON manipulation library - shared library
iU libjson0:i386 0.11-4ubuntu2.1 i386 JSON manipulation library (transitional package)
:

そこで、それらのファイル(ライブラリ)が壊れたかと思い、メンテの前(5/11)にバックアップされていたもの※と比較したら、下記のように中身が違っていた。

$ md5sum {/,}lib/x86_64-linux-gnu/libjson-c.so.2.0.0
db908af9fa464b97b899e0b941019655 /lib/x86_64-linux-gnu/libjson-c.so.2.0.0
215d2780de0df769cb336679c06be7cb lib/x86_64-linux-gnu/libjson-c.so.2.0.0

※定期的に自動でクラウドにバックアップしていたのが役に立った!!

ログ(先日落ちたせいで後半が壊れている)を見る限り、メンテ前後にこれらは更新されていないので、(理由は不明だが)破損したようだ。なお、i386版も同様に違っていた。また、libjson0のファイルは無関係だった。

そこで、破損しているlibjson-c2のライブラリ2個をバックアップされていたものに交換して再起動し、パニックの起こったコマンド(sudo dpkg --configure -a)を実行したら、嘘のように成功した。更に、パッケージ情報の更新も成功し、PHPの更新すらスルッと行った。

結局、サーバが落ちた原因や過程を推測すると、以下のようになる。

  • メンテの頃(?)に、なぜかパッケージlibjson-c2内のライブラリが壊れた。
    • もしかしたら、メンテの終わる時刻の数分前に起動したために、中途半端な状態になったのかも知れない。
    • あるいは、メンテ後の起動直後にlibjson-c2の更新が行われ、システムが不安定だったので、成功したとされつつも、実は失敗していたのかも知れない。
    • あるいは、メンテ(物理サーバの移動)でのデータ移動がうまく行かなかったのかも知れない。
    • あるいは、メンテ前から別の問題で壊れていたのかも知れない。
      • 例: 物理サーバの劣化でディスクのその箇所が壊れた??
    • 実は、サーバ内で壊れたのでなく、元々(パッケージの提供元で)壊れていたか、自動更新時のダウンロード時に壊れたか、壊れはしなかったが、(なぜか)このサーバに合わない版がインストールされた。: この場合、再発する可能性が高い。 → (5/29 7:37) これが原因だった。壊れていたのでなくパッケージにバグがあったようだ。そして再発した。。。
  • libjson-c2は重要なので、壊れた状態ではパッケージ操作が失敗したり、OS(カーネル)がパニックで落ちるなどの問題が起こるのだろう。
  • 最初に落ちた時は、偶然、自動更新が行われて、今回パニックの起こったコマンドと同様の状況になって落ちたのではないか。

ライブラリが壊れた理由が分からず怖いが、他は問題なく動いているので、データ移動の失敗とは考えられない。すると、メンテ後の最初の起動が変な感じだったので、起動がちょっと早かったのかも知れないし、プロバイダが交換するくらいなので、ハード(HDD)の不調はありそうだ(少なくとも、僕が使ってから(推定約十年)は24時間連続稼働している)。それから、壊れた・おかしなパッケージが来た可能性は少ない。インストールの前に、チェックサムなどで正当性がチェックされるはず(未確認)だからだ。ただ、提供元の不手際で違うものが来た可能性は0ではない。駄目だったファイルを詳しく調べれば何が悪かったか分かるが、ちょっと面倒だw

謎(ライブラリが壊れた理由)はまだ残っているが、ひとまず、元の謎が解けたし、いつも「意味あるんかいなー?」と思って居たw、定期自動バックアップが威力を発揮したのも良かった^^ 本当に、コマンド一個で過去のファイルが取得できた(バックアップを繰り返しても、数か月前までの履歴が残っているので、今回、壊れたものがバックアップされていたとしても、それ以前のものを見つければ、壊れる前のファイルが得られる)ので、楽ちんだったし安心だった。

だから、履歴が残るバックアップを皆さんに勧めたいが、簡単に使えて安いものはなかなかない気がするなぁ・・・ いや、実際にはWindowsならあるんかな?

 

(2020/5/29 7:37, 8:12) 今朝、パッケージの自動更新時に、再び同じ現象で落ちてしまった。再びlibjson-c2が更新されたためのようだ。とりあえず、libjson-c2を元に戻し、以後はlibjson-c2とそれに依存するlibjson0が更新されないようにした。以下に、更新しないようにするコマンド例を書く。

echo libjson-c2 hold | sudo dpkg --set-selections

調べたら既知の問題だった。そこには「libjson-c2を0.11-4ubuntu2.5に更新すれば直る」(Chris Newcomer (cnewcomer), 2020-05-15)とあったが、今回は、libjson-c2を0.11-4ubuntu2.6に更新しようとして落ちたので、それも違う気がする。いや、一旦ubuntu2.5に更新すれば良かったのかも知れない。もう少し試してみる。

いずれにしてもASAPでOSを更新すべきなのだが、どうにも面倒だ・・・

(2020/6/2 13:20) その後再発し、直接の原因が分かったので暫定対処をした。telinitコマンドに未解決の問題があるようだ。

 

PS. これはクラッキングとかマルウェアの影響とかじゃないと思うが、ちょっと怖いな・・・ とりあえず ここに記録して、忘れないようにしよう(でも、きっと忘れるがw)。

PS2. 自慢する気はないが、これ、普通の人だったら原因が分からずに、「なぜか時々落ちる・・・」になると思うが、まったく「あなたならどうする」状態だw やっぱり、主要なところをバックアップから戻すとか再インストールとかなのだろうか。あるいは、なんか分からず大嫌いになって、「クソが!」とか言って新しいマシン・OSに換える??

PS3. 最後にちょっと言いたいのは、この世の中に「謎」は余りないってことだ。大抵は、論理的に調べれば原因が分かるはずだ。ただ、調べることが難しい場合はある。でも、すぐに「相性がー」とか「たまたま」とか「様子を見ましょう」とか言う連中が一番信用できない。でも、真の謎は確かにある。そんな気はする。

PS4. 検索していたら、この問題は意外なところ(日本医師会: 障害報告◆日レセ オンプレ版 起動不可, 2020-05-15)にも波及していて可哀想になった・・・ (2020/5/29 7:37)

  •   0
  •   0

調べたら2016年の秋にLinuxに移行したようなので、もうすぐ4年経つようだ。もちろんいいことばかりでもないが、トータルでは随分いい。僕にとっては、空気のように当たり前、かつ、自由なシステムだ。(それは当然としてw、)

今日書きたいのは、ディスクが減らないってことだ。システムディスクには、その時手元にあった120GBのSSDを「とりあえず」(足らなくなったら、別のにしようと思って居た)使い、85GBくらいを割り当てている(残りはスワップ(Windowsの「仮想メモリ」)領域)のだが、いまだに25GBも使ってなく、70%以上も空いている。これ、壊れる前にフルになることがあるのだろうか?w

Filesystem 1G-blocks Used Available Use% Mounted on
/dev/sda1 84G 23G 57G 29% /

自分の大容量データ(写真、音楽ファイル、VirtualBoxの仮想ディスクなど)やシステムでも大きいもの(純正バックアップ(timeshift)のデータ)や書き換えの激しいもの(一時ファイル)は別のHDDに入れているけど、Windowsでは全く考えられないことだ。その頃は、自分では特に使っていないのに数年でシステムディスクがフルになって(Windowsの更新後のバックアップファイルが溜まるのだろう)、「クリーンアップ」なんてしても全然空かず、その周期でSSDを交換していた。とんでもないゴミだった。

今のPCのハードは2011年頃に組み立てたもの(本当に「Sandyおじさん」だw)だが、全然遅いと感じたことがない。Linuxもアプリも(僕の使い方も)軽いのだろう。

ただ、古いだけにいつも「そろそろ寿命か」と心配してはいるのだが、まだ兆候がない。ある日突然崩壊するのだろうか・・・ それに備えてスペアはあるが、そっちも古いので、いざという時に動かない可能性もあるw

ただ、メモリは食う。32GB入れているが、気づくと半分超えている。OS自体は全然消費しないが、ブラウザなどのアプリが肥大化している。それで、自作のメモリ使用量監視スクリプトで大食いアプリの使用量が大きくなったら通知を出し、手で再起動するようにしている。ローテクだけど、これが意外に役に立っている。以前はcgrulesengdとかいうプログラムで自動で使用量を制限していたが、今一つ効かないのと、効いてもアプリがうまく動かなくなって不便なので、自分が再起動できる時に手でした方がいいという結論になった。

なお、Spotifyは相変わらず肥大するのが急で、手で再起動するには頻繁で面倒なので、外部プログラム(自作のミニプレーヤー)でアイドル時に自動で再起動している。

 

PS. SSDの寿命が気になって調べてみたら、現在の残寿命("SSD Life Left")が98%で、累積通電時間は約1.8万時間(約2年)なので、トータルで100年くらい持つ計算だから、SSD内のフラッシュメモリについては心配なさそうだ。

なお、SSDの使用量の増加速度については、Linuxに移行した時はVirtualBoxの仮想ディスクを入れていたので直接の比較はできないが、当時の合計使用量が約58GBのようだったので、入れていた仮想ディスクのサイズを40GBとすると、仮想ディスク以外の使用量は約18GBとなり、今日までの増加分は5GBとなる。使用期間は約3.6年なので、増加速度は約1.4GB/年となる。このペースで単調に増えるとすれば、あと42年は持つ計算だが、果たして・・・

(5/18 6:44 少し加筆・修正)

  •   1
  •   0

GMBのトラックIDが変わる問題に対処しオーディオの配置が一段落し、また、先週 鳩よけを改良したら効果があったようで※、TODO・懸案が減って来たと安心していたら、またもや謎・懸案が増えた。

  • オーディオ: イコライザ設定を少し変えただけで耳閉感が再発・・・
  • ブログサーバーが突然落ちた・・・
  • スマフォの電池消費率が増えて全然直らなかった原因は、電池消費率測定アプリだった??

イコライザは、設置や設定を確定しようと特性を再度測定して確認していたら、それまで見落としていた左の156Hzの山に気付い(てしまっ)た。(参考: グラフの水色線) それで、その山を下げるためにフィルタ1個の設定を本当にほんの少し変えた(中心周波数を5Hz下げ、幅を0.02広げ、減衰量を1dB増やした)だけで、途端に耳閉感が起こるようになってしまった。時間をおいて何度か試したが、その設定にすると30分くらいで起こる。

特性は良くなったのに駄目な理由が全く分からない。変更したことで歪や位相ずれが増えたのかと思って調べてみたが、顕著な違いは見られなかった。もちろん、超低域や高域にも変化はない*。以前から気付いていた、イコライザの種類や設定に関係するものなのだろうが、今回はその経験則から外れていないし、こんなに微妙だとは思わなかった。全くお手上げなので、直す前の設定にしている。

*今、イコライザ変更後の特性(下に載せる)を確認したら、左だけ超低域(33Hz辺り)が7dBくらい増えていた。その時は、近所の工事やエアコンの騒音がたまたま入ったのだと思って居たが、これが原因なのかも知れない。全く関係ないフィルタの変更の影響が出たのだろうか? パワーがある時に確かめたい。もしかしたら、イコライザの経験則は こういうことに関連しているのだろうか。

イコライザ変更前後の特性: L: 水色(前), 紫(後); R: ピンク(前), オレンジ(後); LR: 黄緑(前), ベージュ(後)

ブログサーバーは、今朝、PCからカレンダーの予定を変更した時に落ちた感じだ。カーネルがパニック(例えでなく、こういう用語がある。要するに、「想定外の問題が起こったので落ちまーす」みたいなもの)になったようだが、パニックのためログには何も記録されておらず、仮想コンソールに出ていた断末魔の叫び(パニックのメッセージ)しかないので、全く原因不明だ。

先日のメンテ(物理サーバの移動)で仮想HWが変わったことが関係している気はするが、変わったといってもx86(64bit)機に変わりはなく、特にハードに依存させていないので、まともに動かないのがおかしい。カーネルが随分古いので、更新すれば直るかかも知れない。ただ、それなら、もう少しあとを予定していたが、OSのバージョンを上げたい。が、それはそれでかなり神経を遣うので、頻発するなら、とりあえずはカーネルかな。

スマフォの電池消費率は、去年の夏頃に気付いてずっーと試行錯誤して来たものの、どうにもならなかったのだが、先日、再起動後に現象が起こらないのに気付き、もしかして、電池消費率を測るために入れていたアプリ(GSam Battery Monitor, 以下GSam)を起動しなければ(正確には、開かなければ)、問題(電池消費率が増え、CPU使用率が100%のままになる)が起こらないのかと思って、数日間GSamを開かずに試しているが、今のところは再現していない。アイドル時の電池消費率は、以前のように0.5%/h以下(例: 昨夜から今朝の値: 0.35%/h)になっていて、満足だ。

最初に問題に気付いた時はGSamは入れていなかったので、これだけが原因ではなく、きっと、(当時の)Google Play開発者サービスが悪かったのだと思うが、実はGSamも極悪だったようだ。もしそうなら、こいつのために、ずっと試行錯誤させられて来たので損害賠償請求したいくらいだw まあ、これで直れば、懸案も謎も減るからいい。それにしても、GSamに限らず、電池消費率測定アプリは電池を食うことが多く、ミイラ取りがミイラになるようなもので、しっかりしろと言いたい。今使っているMy Battery Monitorは大丈夫そうだ。ただ、グラフが出ないのでちょっと不便ではある。

 

※鳩よけについては書こうと思っていたが、別件があって面倒だった。簡単に書くと、その前に改良した時に室外機の上用のワイヤーに隙間ができていて(下から見ても分からない)、先月の終わり頃から鳩が入り込むようになった。それで、ワイヤーを均等にし(デジカメで撮影して確認した)、余っていたステンレスワイヤーをそれらのワイヤーに緩く巻いて隙間を塞いだら、今のところは大丈夫だ。ただ、どうも、鳩はこっちが何かしてから少し経ってから来るようなので、油断はできない。

  •   0
  •   0

(身から出た錆?に追われて疲れた話: 僕しか使っていないソフトの話で普遍性がないが、なるべく一般的に書く。)

数日前、PCを再起動した後に、Linux用音楽プレーヤーgmusicbrowser(GMB, 「僕版」)の再生履歴を自作の音楽再生履歴・感想記録システムMlhiのwebで見たら、アルバム画像がおかしいのに気付いた。別のアルバムの画像が表示されていた。実はこれは今年の3月頃にも起こっていて、GMBの曲の番号(ID)が詰められた(昔のBASICのリナンバーみたいなもの)ため、MlhiのDBに登録されたIDとずれて、別の曲のアルバム画像がGMBから取得・表示されることが分かったので、その時はIDを詰める処理をスキップするようにして解決したと思っていた。

僕としては、ユニーク(重複しない)かつ不変であるべきIDを詰める(変える)なんて意図が理解できない※。詰める理由はライブラリ内の曲が削除されたからだと想像しているのだが、IDは整数で、今は少なくとも32ビット(64ビットだって行けるだろう)だから、少なくとも2000万、あるいは4000万曲には割り当てられるから、使い放題だ。だから、曲を削除してもIDを詰める必要は全くない。にも関わらず、なぜそんな危険で無駄なことをするのだろうか。まあ、作者の思想とか気の迷いなのだろう。

※こういうのが、いわゆる「想定外」問題だ。「普通はないよね」って思うことは、実はいくらでもあるのだ。普通なんて幻想だ。そして、全部「想定外」と言えば何でも許される訳ではなく、どこまで想定したかがポイントだ。偉い人たちは、そこが分かってない(、というかうまく逃げているのだろう)。

それから、そういう事態になってもなるべく破綻しないように作るのも、設計・開発者のセンスとか能力だ。

それに、曲の削除にしたって、個人で何千万曲も入れる訳じゃないから多少無効な曲があったって、(今もそうしているように)フラグだけ設定してエントリは削除せず、残しておいてもいい(それが気になるなら、DBの構造をちゃんとすべきなのだ)。

これに似た問題として、マイナンバーの番号不足を想像する。(以前書いたが、)僕の計算では遅かれ早かれ足りなくなると思うのだが、いつかリナンバーするのか、あるいは、また作り直すのか。

のだが、やっぱり再発した。こういう根深い問題は大抵再発して、なかなか直らないと相場が決まっているので、「やっぱり」と思うとともに結構がっかりした。

IDを詰めないようにしたつもりなのに、なぜかまだ詰めるようだ。もちろん、作者は行方不明で聞くことはできず、直してももらえないので、自分で解決するしかない。そして、3月に(いや、それ以前から)思ったが、GMBは超大嫌いなPerlで書かれているうえに、内部構造が妙に凝っていて理解不能なので、根本的に直すことができない。

仕方ないので、MlhiがGMBの曲を指定するのにGMBのIDでなく、別の新しいIDを使うことにした。結構大改造なので、なるべく避けたかった。まあ、そもそも、GMBのIDの仕様を確認もせずに勝手に(ユニークかつ)不変と思い込んで使った僕が悪いので、全く身から出た錆ではあるが、なかなか大変だった。

大改造だけど、なるべく変更を少なくしたかった。そこで、MlhiのDBの構造は変えず、GMBのIDを入れていたプレーヤー固有のトラックIDを格納するフィールド(カラム)に格納する内容を変えることにした。GMBのIDの代わりに、曲の音響的な特徴から生成したID(今までもMlhiのトラックID(メインのキー・ID)として使っていたもので、AcoustIDのfpcalcコマンドで計算している)を格納するようにした。GMBのIDと新しいIDはプリフィクスで識別できるようにして、同じフィールドに混在可能にした。なお、この新しいIDは、当然ながらGMBのDBにも登録し(フィールドを追加した)、GMBのIDがいくら変わっても(その新しいIDで)同じ曲が検索できるようにした。

GMBに曲の固有ID(utid)を追加した("Track ID"の列)。まだ再生していない曲("Today's girl")では空だが、再生すると自動で設定される(「ザ・ベスト」)。"ID"は従来のGMBのID(固有でない)。

また、そのようなDBの中身の変更をバッチ処理(SQL)で行うのは失敗のリスクがあったので※、使いながら自動的に変更するようにした。つまり、GMBでの曲の再生時(Mlhiへの履歴の登録時)に、既存の曲のプレーヤー固有のトラックIDのフィールドに昔のID(GMBのID)が入っていたら、新しいID(曲の特徴から生成したID)に入れ替えるのである。

※実際、MlhiのDBは確認のためにしかツールで開いていなかったのに、いつの間にかDBのエントリが一個空になっていた・・・ 間違って何か押したか、修正中に(あるいはもっと前に?)バグが出たのかは不明だ。 ← バックアップを調べたら、変更版を試している時に誤動作して消えたようだ。

なお、曲の特徴からIDを生成するのは、今まではMlhiに履歴を登録するプログラム(登録プログラム)で行っていたが、そのIDをGMBにも格納するようになったので、GMBで生成して登録プログラムに渡すようにした。

余談だが、PerlからID生成プログラムを実行する時、曲のファイル名に日本語が入っていると文字化けして、どうしても直らなかった。ごく当たり前のことすら普通にできないのでブチ切れそうになったが、仕方ないので、Base64でエンコードしてプログラムに渡すようにした。

もう、とにかくPerlなんて1文字だって見たくない!! 何もかもオカシくぐちゃぐちゃで※、見るだけでイライラが溜まる。Perlだったら断然Pythonの方がいい(でも、僕にはPHPが一番だ)w 良くあんなものでまともなプログラムが書けるものだ。そこには感心する。

※"my"や"our"なんてセンスが悪いし、関数(サブルーチン)の引数は(,)で囲い区切ってってもそうでなくてもいいなんて見難いし、$とか@とか%とか()とか[]とか{}とか=~とか\とか、とにかく記号が多過ぎて(しかも、それらの複合もある)、「いい加減にしろ!」だ。

GMBの場合の処理の流れの概要は、以下のようになる(Spotifyでは曲の固有IDがISRCになっている以外は概ね同様)。

曲の再生開始

GMB

  1. 開始から指定時間(例: 3秒)後に、以下を実行する(すぐにスキップした場合は登録しないようにしたかったため)。
  2. その曲に固有ID(utid)が設定されていなければ、音響的特徴から生成して、GMBの曲DBのutidフィールドに格納する。+
  3. Mlhiに再生開始を通知する(utidを指定)。

Mlhi(履歴登録プログラム)

  1. 指定された曲が以前再生したことのあるか(指定されたutidがトラックIDのエントリがDBに格納されているか)調べ、なければ(初めて再生する曲)そのエントリを作成する。その時、GMBから曲の情報(例: タイトル、アーティスト、アルバム)を取得する(utidで曲を指定する)。
  2. 以前再生したことのある曲の場合、DB内のプレーヤー固有のトラックIDがutidでなかったら、指定されたutidに置換する。+
  3. 再生開始日時をDBに記録する。また、再生回数を+1する。

曲の再生終了

GMB

  • Mlhiに再生終了を通知(utidを指定)する。併せて完奏率も送る。

Mlhi(履歴登録プログラム)

  • 再生終了日時と完奏率をDBに記録(追加)する。完奏率は、それまでの完奏率と合わせる処理をする(履歴表示時に平均の完奏率を求めるため)。

曲の再生履歴の表示

Mlhi(web)

  1. DBから再生履歴を抽出し、GMBの曲の場合には、アルバム画像のファイル名や曲の長さなど(履歴には関係なく自明なため)DBには格納していないが、履歴表示にはあった方がいい追加情報をGMBから取得する(utidで曲を指定する)。
  2. その他の情報(例: コメント、評価)をDBから抽出し、履歴と共に成形して表示する(→ )。

※今回追加した処理は項目の最後に"+"を付けて示した。

 

変更を少なくしようとはしたけれど(実際、処理の流れの本筋は何も変わっていない)、やっぱり結構多くなり、昔作ったのですっかり忘れていたこともあって大変で、4日くらい掛かった(ている)。その間は、例によって、気付くと一日が終わっていたり、食事中にもバグが見付かったりして、全く気が休まらなかった。更に、昔の誤り(しかも、関係ないところにも!)も結構あって、「どんなものでもテキトーに作ってはいかん」と思い知らされた。。。

とは言え、何でもきっちり作っていたら、終わらずに使えなくなってしまう(機会を逃す)ので、そこの見極めが難しい。そこら辺もセンスや能力なのだろう。

そして、動作確認して基本的にはOK(何度も戻って修正した)だったのだが、そもそもの、GMBのIDのリナンバーが起こらず、本当に効果があるのかが確かめられない。曲を削除しても強制終了しても、なぜか起こらない。どうにも挙動不審なプログラムで、そういうのを使い続けるのもどうかとは思うのだが、他にいいものがないので仕方ない(いつかは自分で作り直したいが、無理だろうな)。

問題の現象が再現しないのでは仕方ないので、定期的にGMBのIDのリナンバーが起こったかどうかを検出するように定期実行機能(crontab)に設定しておいて、起こったら改めてアルバム画像を確かめることにした。

 

なお、僕しか使っていないものなので、他の方では直ったどうかも判然としないからキャプチャを載せても意味がないが、以下のように直った(単なる自己満足で載せるw)。

問題修正後のMlhiの再生履歴のアルバム画像

図中の"FCM5:"で始まるのが、曲の特徴から生成したIDである(それをGMBの新しいIDにも使っているので、"GMB:FCM5:-"と略記している)。また、"AIM5:"はアルバムのIDである。

 

PS. 当然ではあるが、曲の特徴から生成するIDは、同じ曲(ファイル)ならいつ何回生成しても同じ値になり(昔生成した値と今回生成した値が同じだった)、まだ重複していないので、ちょっと感心した。

PS2. 誰も気にしてないはと思うが、僕が好きなのは80年代のコイズミまたはkyon2であって、現代のダサい小泉さんではない。この投稿は妙なタイミングになったが、そこのところははっきりさせたいw (5/11 19:28)

 

(5/11 9:10 画像を追加、わずかに加筆・変更; 18:52 処理の流れの概要を追加、その他に加筆)

  •   1
  •   0

Linux用のEvernoteクライアントはなかなかいいものがないのだが、僕はNixNote2を「だましだまし」使っていた。しかし、問題が多過ぎる。例えば、下手にコピペすると(→ テキストと画像を混ぜてペーストすると確実にアウト)ノートが編集できなくなるので、神経を遣いながら使っているのだが、それでも、大体数か月に一回問題が起こる。

推測だが、スマフォ(Androidアプリ)でノートを開くのがすごく遅い(ノートが大きいと、まず開けない)ことが多いのは、NixNote2のフォーマットがおかしいせいじゃまいか?

昨日からは、アプリを起動するたびに、下記のような認証関係のエラーが出てノートが同期しなくなってしまった。

ERROR 2020-04-25 07:40:58.550 src/communication/communicationerror.cpp:86 "StdException[16]: Error downloading https://www.evernote.com/edam/user - server replied: OK"

メッセージを見る限り、サーバーから"OK"を返されたのだから問題はないと思うのだが、なんか頭が悪いようだ。

この状態から回復するには、再度Evernoteの認証を行う必要があり、大変煩雑でイライラする。仕方ないので、Tusk(web版Evernoteをアプリ化したもの)を使うことにした。Tuskはノート内の検索ができず、複数のノートを同時に開けないし、ノートのバックアップもできないから不便なのだが、NixNote2よりは安定してそうだ。

ただ、そんなに不便なら普通にブラウザでweb版を使えばもいい気がしてきた。。。 (なんでアプリ化したものを使おうとしたんだっけ??) まあ、いい方を選ぼう。

(19:04) Tuskはやっぱりイマイチだし無意味なので、web版を使うことにした。新UIというのが結構良くなっていたので(例: ペーストした画像がカーソルの位置に来る(以前は必ずノートの最後だった))、良かった。そして、NixNote2では書こうとするたびにちょっとした問題なり気を遣うことがあってストレスフルだったのだが、それがなくなって大変気持ちがいい。まあ、こっちにはこっちの欠点はあるだろうが(だからNixNote2を使っていたはず)、とりあえず「普通に使える」のはいいことだ。

それでも、今回は一ついいことがあった。Linux用Evernoteクライアントを検索したら、今年の頭に、EvernoteのCEOがLinux版の純正アプリを作っていると書いていたらしいことが分かったのだ。まあ、コロナの影響で遅くなるかも知れないし、そもそも本当に出るかも分からないが、少しだけ希望ができた。

 

PS. もう一ついいことがあった。: Tuskやブラウザなら、(自作の)マウスホイールの加速処理にも普通に対応するので、やっぱりこっちがいい。ちょっと使ったが、Tuskには特段にいいことがないので(ではなぜ、作者は作ったのだろうか?)、ブラウザにしようと思う。

PS2. Web版でもノートをバックアップできず、Windows版はWin7(仮想環境で動かしていて、NWを切断している)がサポート終了でいろいろ面倒が起こりそうなので、バックアッププログラムを作ろうかと思っている。

EvernoteのAPIは公開されているが、最初から作るのは面倒なので、既存のもの(Geeknote)などを改造できないか調べてみたい。Geeknote(正確には、その一部のgnsyncコマンド)はノートをプレインテキストやマークダウンでダウンロードできるが、画像などはできないので、そこを何とかしたい。

(18:58 わずかに補足・修正)

  •   0
  •   1

[English follows]

先日、「[Linux] マウスホイールの加速ができた! (PoC)」で触れたプログラムの公開の要望を頂き、検討したところ、不足な点や問題はあるものの、いろいろやって遅くなるよりは、とりあえず使って試して頂くほうがいいと考えたので、今私が使っている版をV0.1として公開します。

より多くの方にお試し・使用して頂ければと思い、日英両方で記載します。日本語版を先に("[English follows]"や"[Ja]"の後や"/"の前に)書き、英語版は"[English]"や"[En]"や"/"の後に書きます。

(2020/4/16 8:16) NixNote2などでの動作の改善や、Cコンパイラがない・コンパイルしたくない場合などにxdotoolを使う機能などを追加した、V0.2を公開しました。

[English]

A few days ago, I have been asked to publish my own program "acc-wheel" which accelerates Linux/X11's mouse wheel (it has been introduced in my past article "[Linux] Succeeded in accelerating mouse wheel! (PoC)" (written in Japanese)). Although it is not complete (has some problems and limitations), it is better to publish now and made it evaluated and used than continue working on and being "too late". So, I would like to publish current version of the software as "V0.1".

Because I would like the software to be evaluated or used globally, this article is written in both Japanese and English. Japanese descriptions are first (after "[English follows]" or "[Ja]", or before "/"), and then English ones (after "[English]", "[En]", or "/").

(2020/4/16 8:16) Released V0.2, which improves behavior on some apps. (eg. NixNote2), can use xdotool for envs. without C compiler, or for who don't want to compile, and other improvements.

1. ソフトウェアの説明 / Software description

1.1 概要 / Abstruct

[English follows]

acc-wheelは、X Window System (X11)の動作しているデスクトップLinuxでWindowsやmwillacOSのようなマウスホイールの加速を実現します。これは単にホイールの回転量を常に数倍にする(例: ×2)のではなく、ホイールを回転させる速度に応じて回転量を増やす「真の加速」なので、通常の使用時(= ホイールをゆっくり回す場合)に不都合は起こりません。

また、ドライバなどの特別なプログラムでなく通常のプログラムなので、起動するだけで手軽に使えます。

ただし、実行するユーザーがマウスのイベントデバイスを読み出せるように、あらかじめユーザー情報を設定する必要があります。また、V0.1では、マウスイベントを発生させるためのプログラムのコンパイルが必要です。

[English]

acc-wheel implements mouse wheel acceleration as in Windows or macOS on desktop Linux systems running  X Window System (X11). This is not simply multiplying wheel rotation with fixed number (ie. ×2), but a "true acceleration", which increases the amount of rotation according to the speed of rotating speed of the wheel. So, inconvenience never happens in ordinary usage (ie. when rotating the wheel slowly).

In addition, because this is an ordinary program (not special one like device driver), you can use it very handy - just start it.

Notes: Before using, you have to make your user account to be able to read mouse's event device. And, V0.1 requires compilation of an accompanied C program which generates mouse events.

1.2 動作 / Opeation

[English follows]

acc-wheelの処理概要は以下のとおりです。

  1. マウスのイベントデバイス(例: "/dev/input/by-id/usb-Microsoft_Comfort_Mouse_6000-event-mouse")からイベントを読み出す。
  2. ホイールイベントだった場合、イベントの発生速度(= ホイールの回転速度)を求める。
  3. 速度が高速だった場合、追加のホイールイベントを発生させる(→ ホイールの「加速」になる)。
    • 追加のイベントの量(= 加速の度合い)は以下の3つのモードで選択可能。
      • S (ステップ)モード: イベントの発生速度がとても速い場合、より多くの追加イベントを発生させる。 (デフォルト)
      • L (比例加速)モード: イベントの発生速度に比例した追加イベントを発生させる。
      • LS (遅目の比例加速)モード: Lモードと同様だが、少な目の追加イベントを発生させる。
  4. 1に戻る。

[English]

Overview of acc-wheel's process is as follows:

  1. Read events from mouse's event device (eg. "/dev/input/by-id/usb-Microsoft_Comfort_Mouse_6000-event-mouse").
  2. If the events are from wheel, calculate event generation speed(= wheel rotation speed).
  3. If the speed is fast, generate additional wheel events (→ become "acceleration" of wheel rotation).
    • Amount of added wheel events (= amount of acceleration) can be chosen in the following three modes:
      • S (Step) mode: If the speed is very fast, generate more events.
      • L (Linear) mode: Generate events proportionally to the speed.
      • LS (Slow linear) mode: Like L mode, but generate less events.
  4. Go to 1.

1.3 環境 / Environment

1.3.1 対応・要求環境 / Supported/required environment

  • X11の動作しているLinuxデスクトップ / Desktop Linux running X11.
  • マウスがイベントデバイスになっていること("/dev/input/by-id/usb-マウス名-event-mouse"がある)。 / The mouse is an event device (ie. Mouse's event device exists as "/dev/input/by-id/usb-Mouse-name-event-mouse".)
  • 実行するユーザーがマウスのイベントデバイスを読み出せること。 / The user has a read permission to the mouse event device.

1.3.2 必要なソフトウェア / Required software

  • PHP言語 / PHP language processor
    • 例: Ubuntu系の場合、php-7.3, php7.3-cliパッケージ / Eg.: php-7.3 and php7.3-cli packages for Ubuntu
  • X11の開発パッケージ / X11 dev. package
    • 例: Ubuntu系の場合、libx11-dev / Eg.: libx11-dev for Ubuntu
    • 使用X11ライブラリ / X11 libraries used: libX11, libXtst, libXext
  • [V0.2: なくても可 / V0.2: Not mandatory] Cプログラム(gen-mouse-ev.c)のコンパイルのため、gccまたは他のCコンパイラ。 / gcc or other C compilers (to compile accompanied C program: gen-mouse-ev.c).
  • [V0.2 のみ / V0.2 only] xdotoolコマンド (マウスイベントを発生させるためにgen-mouse-ev.cの代わりに使う場合) / xdotool command (when using it to generate mouse events instead of gen-mouse-ev.c)
    • 例: Ubuntu系の場合、xdotoolパッケージ / Eg.: xdotool package for Ubuntu

1.3.3 開発・確認環境 / Developed and tested env.

Linux Mint 18.3 Xfce

1.3.4 ユーザーによる動作確認済み環境 / Reported working envs. by users

2. デモ動画 / Demo movie

Linux Mint XfceにてFirefoxブラウザでホイールを回転させた比較 / Comparison of rotating the wheel on a Firefox browser running on Linux Mint Xfce.

通常の場合(acc-wheelを起動させず)にホイールを速く回転させた場合 / Rotating the wheel fast in ordinary situation (without running acc-wheel).

 

acc-wheelをSモードで動かし、ホイールを遅く回転させた場合 / Running acc-wheel in S mode, rotating the wheel slowly.

 

acc-wheelをSモードで動かし、ホイールを速く回転させた場合 / Running acc-wheel in S mode, rotating the wheel fast.

 

acc-wheelをSモードで動かし、ホイールをとても速く回転させた場合 / Running acc-wheel in S mode, rotating the wheel very fast.

 

3. ダウンロード / Download

acc-wheel-0.2.1.tar (md5sum: 77aac373e8799d9b9374b4fac035f4d8)

(Old version: acc-wheel-0.1.tar (md5sum: ab8f590f11146b484741a1646bc4c2d8))

Releases also available on GitLab.

4. インストール手順 / Installation

[English follows]

4.1 標準的な手順 (特にUbuntu系の場合)

  1. 実行するユーザーがマウスのイベントデバイスを読めるようにする。 (例: ユーザーIDをマウスイベントデバイスのグループ(例: input)に追加する。)
    1. マウスイベントデバイスのパーミッションを確認する
      • 例: ls -lL /dev/input/by-id/usb-Microsoft_Comfort_Mouse_6000-event-mouse
      • crw-rw---- 1 root input 13, 68 4月 8 08:08 /dev/input/by-id/usb-Microsoft_Comfort_Mouse_6000-event-mouse
    2. デバイスがグループ(例: input)での読み出し可の場合、ユーザーID(例: user)をそのグループに追加する。
      • 例: sudo usermod -G input user
    3. Linux・デスクトップにログインし直す。
  2. acc-wheelの作業用のディレクトリを作るか既存のものに移動する。
    • : cd ~/work
  3. ダウンロード・展開する。 → ディレクトリ "acc-wheel"ができる。
    • :
      • [V0.1] wget -O - https://piulento.net/bsw/acc-wheel/acc-wheel-0.1.tar | tar xf -
      • [V0.2] wget -O - https://piulento.net/bsw/acc-wheel/acc-wheel-0.2.tar | tar xf -
  4. [V0.2では省略可] acc-wheelにchdirし、gen-mouse-ev.cをコンパイルする。 → マウスイベントを生成するプログラムgen-mouse-evができる。
    • : cd acc-wheel && gcc -o gen-mouse-ev gen-mouse-ev.c -lX11 -lXtst -lXext
  5. [V0.2のみ] マウスイベントを発生させるのにxdotoolを使う場合、xdotoolをインストールする。
    • 例: sudo apt-get install xdotool

[English]

4.1 Standard steps (ie. on Ubuntu systems)

  1. Enable your read access to your mouse event device (eg. add your user ID to mouse event device's group (eg. input)).
    1. Check mouse event device's permission.
      • Eg.: ls -lL /dev/input/by-id/usb-Microsoft_Comfort_Mouse_6000-event-mouse
      • crw-rw---- 1 root input 13, 68 4月 8 08:08 /dev/input/by-id/usb-Microsoft_Comfort_Mouse_6000-event-mouse
    2. If the device can be read by group (eg. input), add your id (eg. user) to the group.
      • Eg.: sudo usermod -G input user
    3. Re-login to the Linux/desktop.
  2. Make or choose a work dir. for acc-wheel and chdir to it.
    • Eg.: cd ~/work
  3. Download the archive and extract. → Dir. "acc-wheel" will be made.
    • Eg.:
      • [V0.1] wget -O - https://piulento.net/bsw/acc-wheel/acc-wheel-0.1.tar | tar xf -
      • [V0.2] wget -O - https://piulento.net/bsw/acc-wheel/acc-wheel-0.2.tar | tar xf -
  4. [V0.2: Not mandatory] Chdir to acc-wheel and compile gen-mouse-ev.c. → Program to generate mouse event "gen-mouse-ev" will be made.
    • Eg.: cd acc-wheel && gcc -o gen-mouse-ev gen-mouse-ev.c -lX11 -lXtst -lXext
  5. [V0.2 only] Install xdotool when using it to generate mouse events instead of gen-mouse-ev.
    • Eg.: sudo apt-get install xdotool

4.2 参考: ユーザーから頂いた情報 / Supp.: Information from users

4.2.1 Fedora31 Gnome3でのインストール / Installation on Fedora31 Gnome3 (2020/4/14: 匿名 / anonymous)

  • 以下のパッケージを追加でインストールする。 / Install additional packages as the following steps:
    • sudo dnf install libXtst-devel
    • sudo dnf install php-cli
    • sudo dnf install php-process
  • マウスのナチュラルスクロールの設定はoffにする必要あり。 / Mouse's "natural scrolling" has to be disabled.

5. 使用手順 / Usage

  1. acc-wheel.phpを起動する。 / Run acc-wheel.php.
    • 書式 / Synopsis: php acc-wheel.php [-m S|L|LS] [-d[v]] [-v|-q] [-xdt] [-h] [mouse-event-dev-name] (-xdt, -h: V0.2のみ / V0.2 only)

      • -m: 加速モード / Wheel acceleration mode
        • S: ステップ加速モード (デフォルト) / Step acceleration mode (default)
          • [Ja] ホイールの回転速度がとても速い場合、より多く加速する。
          • [En] If the wheel speed is very fast, acceleration becomes large.
        • L: 比例加速モード / Linear acceleration mode
          • [Ja] ホイールの回転速度に比例した追加イベントを発生させる。
          • [En] Accelerate proportionally to the wheel speed.
        • LS: 遅目の比例加速モード / Slower linear acceleration mode
          • [Ja] Lモードと同様だが、少な目の追加イベントを発生させる。
          • [En] Like L mode, but smaller acceleration.
      • -d, -dv: デバッグモード / Debug mode (-dv: より多くの情報を出力する / more verbose)
      • -v: 冗長モード (デフォルト) / Verbose mode (default)
      • -q: 非冗長モード / Quiet mode
      • [V0.2] -xdt: マウスイベントの発生させるのにgen-mouse-evでなくxdotoolを使う。 / Use xdotool instead of gen-mouse-ev to generate mouse events.
      • [V0.2] -h: 使用法を表示する。 / Show usage.
      • mouse-event-dev-name:
        • [Ja] マウスイベントデバイスのパス (例: /dev/input/by-id/usb-Microsoft_Comfort_Mouse_6000-event-mouse)
          • 指定しない場合、自動でマウスを検索し、最初のものが使用される。
        • [En] Path of mouse event device (Eg.: /dev/input/by-id/usb-Microsoft_Comfort_Mouse_6000-event-mouse)
          • If not specified, system's mice are searched automatically and the first one will be used.
    • 実行例 / Example: php acc-wheel.php < /dev/null>& /dev/null &
  2. マウスホイールを速く回転させると、ウインドウのスクロールが加速されます! / Scroll mouse wheel faster, and the window's scrolling speed will be accelerated!

参考: マウスイベント生成プログラム: gen-mouse-evの使い方 / Supp.: Usage of mouse event generation program: gen-mouse-ev

  • 書式 / Synopsis: gen-mouse-ev [mouse-button-syms...]
    • mouse-button-syms: 生成するマウスボタン記号(番号) / Mouse button symbols (numbers) to generate.
      • 1, 2, 3, ...: ボタン番号 / Button number
        • 4: ホイール上向き / Wheel up, 5: ホイール下向き / Wheel down
      • Sn: n (ms)スリープする / Sleep n (ms).
      • C: XSyncを実行する / Perform XSync.
      • 指定しない場合、マウスボタン記号を標準入力から取得する。 / If not specified, mouse button syms. are obtained from stdin.
        • ボタン記号と改行(\n)を入力して行く。 / Specify one button sym. per line. Each line ends with newline(\n).
        • 空行の場合はXSyncを実行する / When empty line entered, XSync is performed.
  • 実行例 / Example
    • ./gen-mouse-ev 4 C S200 4 :  ホイール上, XSync, スリープ200ms, ホイール上 / Wheel up, XSync, Sleep 200ms, Wheel up
    • echo -e "4\nC\nS200\n4" | ./gen-mouse-ev : 上と同じ(標準入力から読む) / Same as above (button syms. are read from stdin).

6. 調整 / Tweaks

  • 加速特性の調整 / Adjusting acceleration mode/rate.
    • acc-wheel.phpの-mオプションでモードを変える。 / Specify acc. mode with -m option of acc-wheel.php.
      • acc-wheel.phpの変数$wheel_acc_configsに各モードの加速パラメタが定義されている。 / Params. of each mode are defined in $wheel_acc_configs in acc-wheel.php.
  • ブラウザの「スムーススクロール」はoffにしたほうがいい。 / It 's better to disable browser's "smooth scroll".
  • うまく動かない場合、マウスのイベントデバイス(/dev/input/by-id/usb-マウス名-event-mouse)のモードを確認すること。 / If acc-wheel doesn't work, check the permission of mouse event device (/dev/input/by-id/usb-mouse-name-event-mouse).

7. 制限事項・既知の問題 / Limitations and known problems

  • 対応するマウスは1個だけ。 / Only one mouse is supported.
  • 加速されたホイールイベントが少し遅れて出ることがあり、思わぬ結果になることがある。 / Sometimes, generation of accelerated wheel events are delayed and unexpected behavior may occur.
  • アプリケーションによっては(例: NixNote2)、今ひとつ正常に動作しない。 / Some applications (eg. NixNote2) doesn't handle accelerated wheel events well. → V0.2で改善した。 / Improved on V0.2.
    • [Ja] [NixNote2, digiKam6] ホイールを速く回した時のスクロール量がおかしい(スクロールしない、変なところにジャンプする、もたつく)。
    • [En] [NixNote2, digiKam6] When wheel speed is very fast, scrolling amount is not right (eg. doesn't scroll, jump to unexpected loc., or scroll amount is very small).
  • [V0.2] [xdotoolを使用する場合: -xdt] 追加ホイールイベントを発生させるたびにxdotoolを起動するので効率が悪い(例: 負荷が少し重くなる)。 / [When using xdotool: -xdt] Because xdotool is invoked every time when generating additional wheel events, the process is not so efficient (eg. CPU load will be a little bit heavy).
    • xdotoolに標準入力からコマンドを指定しても動作しないため。 / Because xdotool does not seems to execute commands read from stdin.

8. TODOs

  • 不具合修正 / Fix problems.
  • 加速パラメタの調整を容易にする。 / Make adjustment of acc. param. easy.
  • その他のさまざまな改良。。。 / And other various improvements...
  • インストーラーやMakefileを作る。 / Make an installer (and Makefile).
  • ☑ GitHubやGitLabなどで公開する。 / Publish on GitHub or GitLab. → 試しにGitLabで公開した。 / Experimentally published on GitLab.

9. ライセンス / License

[English follows]

このソフトウェアはMITライセンスで公開します。正式なドキュメントができるまでは、この投稿も本ソフトウェアの一部とします。

[English]

This software is published under the MIT license. Until formal documents are available, this article should be treated as part of the software.

ライセンス文書 / License text

Copyright 2018-2020 Butty PiuLento

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

10. サポート / Support

[English follows]

ご感想やインストールや使用上の問題などは、この投稿にコメントして下さい。可能な範囲で対応します。

[English]

Any comments would be appreciated, and if you have any trouble in installing and using acc-wheel, please comment to this post. I will support as possible.

11. 謝辞 / Acknowledgement

[English follows]

gen-mouse-ev.cで実行している、XTestでマウスホイールイベントを発生させるアイデアはBharathi Subramanianの"X11 Fake Mouse Events Generation using XTest Extension" (2010)より得ました。

[English]

Idea of issuing mouse wheel events using XTest (performed in gen-mouse-ev.c) was obtained from Bharathi Subramanian's "X11 Fake Mouse Events Generation using XTest Extension" (2010).

 

Mod. history (English only)

2020/4/14 9:40: 11. 謝辞 / Acknowledgement: Corrected "gen-mouse-ev.c" was old name ("send-mouse-ev.c").

2020/4/14 10:03: 1.3.4 ユーザーによる動作確認済み環境 / Reported working envs. by users, 4.2 参考: ユーザーから頂いた情報 / Supp.: Information from users: Added info. of Fedora31 Gnome3 from anonymous user.

2020/4/14 12:13: 5. 使用手順 / Usage: Added gen-mouse-ev's usage as supp.

2020/4/14 17:25: Experimentally published on GitLab.

2020/4/15 13:55: 1.3.2 必要なソフトウェア / Required software: Added php7.3-cli.

2020/4/15 14:21: 3. ダウンロード / Download: Added releases on GitLab.

2020/4/15 20:47: 制限事項・既知の問題 / Limitations and known problems: Added digiKam6 to incompat. apps. Fixed NixNote2's name.

2020/4/16 8:16: Released V0.2 and added the info. Deleted "V0.1" from the title.

2020/4/19 16:29: 3. ダウンロード / Download: Updated to V0.2.1

  •   0
  •   2

(今日も小ネタを)

なぜか ちゃんとしたスクリプトを作る気が起こらず、いつもコマンドの履歴やEvernoteのメモからコピペする処理がある。カップ麺などで3分間待つ時のタイマーだ。

もちろん、スマフォの時計アプリでできるのだが、使うとなぜか電池使用率が増えるので、使わないようにしている。ただ、それが原因かどうかは未確定だ。

あと、Linuxデスクトップにも適当なアプリがありそうだが、ちょっと探していいのがなかったので、面倒だから作った。

以下である(3分間の場合)。メッセージの英語はテキトーなので、イマイチかも。あと、処理もテキトーです。ノークレーム・ノーリターンでお願いしますw

tend=`expr 3 \* 60`; t0=`date +%s`; while true; do date; t=`date +%s`; dt=`expr $t - $t0`; rest=`expr $tend - $dt`; echo "Elapsed $dt sec (rest=$rest sec)."; if [ $dt -ge $tend ]; then zenity --info --text='REACHED TIME!!!'; break; fi; sleep 10; done

以下のように、経過時間を10秒ごとに表示し、時間が来るとダイアログ(zenityを利用)で通知が出る。

2020年 3月 7日 土曜日 11:26:06 JST
Elapsed 0 sec (rest=300 sec).

待つ時間を変えるには、冒頭の変数tend(秒単位の待ち時間)を適宜調整すればいい。

なぜ ちゃんとしたスクリプトを作らないかというと、スクリプトにするといろいろ機能を追加したくなって(例: 待ち時間をGUIで設定、時間が来たら音を出す)、それが面倒だからだと思う。あと、これを使う時はお腹が空いているので、スクリプトなんて作る暇はなく(「えーと、あれどこだ」的に探す)、食べたら満足して忘れてしまうこともありそうだw

 

PS. 今、レトルトカレーを温めるのにこれを探したので、ついでに投稿したw (インスタント食品が好きそうだけど、実は料理が得意そうな)サボり先輩に捧ぐ(爆)

  •   0
  •   0

注意 3か月くらいiVideoを使って何度かトラブルがあったが、SIM・ルーターの管理や障害対応が全く適切でないと感じた。更に、通信障害が起こっても、通信に関してはキャリア任せなのでトラブルシューティングができず、機材(SIM・ルーター)の交換しかできず、それも「様子見しろ」と言って渋るし、交換されるにしても届くのが数日後で、その間は障害はそのままなので、iVideoをメインに使うのはリスクが高過ぎることが分かった。その経験から、iVideoを重要な用途(例: 光回線の代わり)に使うことは全く推奨しない。

具体例については、「[悲報] 完全無線は時期尚早でござった。」を参照のこと。(2020/3/25 6:34)


謎の多いiVideoのモバイルルーター、iV501。余り需要はないと思うが、使ってみて分かったことを書く。なお、以下はiVideo社とは関係なく、すべて私の推測や試行の結果である。質問には可能な範囲で回答するが、余りにも初歩的なものは控えて欲しい。例えば、書かれている単語の意味が全く分からない場合には、まずそこから理解すべきで、安直に試すべきではない。とにかく、自分でトラブルシューティングする覚悟が必要である。

本体のLED

右上の電源LED(後述)以外は全く挙動不審だw おそらく、何かの契機(通信・充電開始や電源ボタンを押したら?)で、それぞれの意味(LTE・Wi-Fi接続の有無)で点灯するが、しばらくすると省電力のために消えるのだろう。ただし、左下のメール(おそらくSMS)のLEDはSMSを受信した場合(未読がある場合?)は点滅無効で、他が点灯する時は常に点灯するようだ。

電源LEDは以下のような規則のようだ。以下では管理webの挙動や関連するweb API: goform_get_cmd_processの変数(前の投稿を参照)についても書く。

  • 充電中の場合
    • 電池のLED: 緑点滅: 1秒間隔 (消えることもある?)
    • Web: 充電しているアニメアイコン
      • 画像ファイル: img/battery_charging.gif
    • APIの変数:
      • battery_charging: 1
      • battery_pers: 4(満充電), 3, ...
  • 残量が充分ある場合
    • 電池のLED: 緑常時点灯 (ボタン操作せずに時間が経つと消える)
    • Web: 普通の電池アイコン(黒い部分が残量に比例)
      • 画像ファイル(残量は推測):
        • img/battery_full.png: 100%
        • img/battery_three.png: 75〜100%
        • img/battery_two.png: 50〜75%
        • img/battery_one.png: 0〜25%
        • ※電源を抜くとすぐにthreeになるようなので、threeでも満充電の場合があると考えても良さそうである。
    • APIの変数:
      • battery_charging: 0
      • battery_pers: 4(満充電, 画像ではfullに相当), 3(画像ではthreeに相当), 2?, 1?
  • 残量が少ない(要充電)場合: まだなったことがないので不明。 (2020/2/29 更新)
    • 電池のLED: 赤常時点灯 (ボタン操作せずに時間が経つと消える)
    • Web: 電池内に赤枠のアイコン (最初に管理webを表示した時に一瞬なるので、これだと推測した): LEDとは基準が異なるようで、赤常時点灯の時も最低レベルのアイコンだった。
      • 画像ファイル: img/battery_out.png
    • APIの変数: (これもLEDとは基準が異なるため、赤常時点灯の時も0でないことがあると推測する。)
      • battery_charging: おそらく0
      • battery_pers: 0?

備考

  • 電源LEDは通信時(ある程度データ量が多い時?)にも点滅するようだ。 ← 違う感じ。電源やPCに接続中は常時点灯? (2/5 17:25)
  • Web APIの変数battery_vol_percentはいつも"100"なので、残量とは関係なさそうだ。接続されている電池の仕様上の容量を示しているのだろうか?

管理web

URLはhttp://192.168.0.1で、最初にパスワード(ここには書かないが、良くあるもの)を入れる必要がある。どうやって分かったのか(他のZTEのルーターと同じなのかも知れない)、パスワードを公開されている方が居たので、私はそれを使っている。

なお、デフォルトの設定では、管理webも他のポートも、外からは接続できない(なぜか"closed"になっている343/tcp以外は応答しない)。ただし、2000/tcp以上のポートについては未確認。 → 外部からの攻撃でiV501を操作されたり、接続している機器が攻撃される可能性は低そうだが、TCP以外については不明だし、何らかのバグを突かれる可能性がないとは言えないので、全く安全と言うことはできない。あと、iV501から外部に情報を流出させている可能性は0とは言えない。

iV501にファイアウォール機能はあるが、機能が今ひとつ貧弱なので実用には向かない。他にポートフォワード機能などもあるが、試していない。

なお、未読SMSがある場合には上部に件数が表示されるが、SMSのタブを押してもなぜか開かない。

注意: 設定を変更して問題が起こってもiVideoのサポートは受けられないので、自己責任で行うこと。また、返却時には初期状態に戻すこと。

PCとのUSB接続

Linux(Ubuntu 16 LTSベース)では、PCに接続するだけでネットワークインタフェースとして認識され、すぐにLTE通信に使える。なお、AndroidスマフォのUSBテザリングとは異なり、接続するポートを変えてもインタフェース名は変わらない。インタフェース名は、擬似的なMACアドレスから作成されるようだ。このMACアドレスはどういう規則なのかは不明である(Ethernetでないので、固定値にしている気がする)。

iV501の内部には仮想CD-ROMも入っており、Windows用ドライバをインストールするアプリが入っている。また、内部(電池の下側, SIMの隣)にmicro SDを挿すと、Linuxにマウントされるはずだが、未確認である。

Linuxでは、接続すると自動的に上記の仮想CD-ROMがマウントされてしまうが、以下の内容のファイルを /etc/udev/rules.d/75-ign-zxic-mb-cd.rules (パスやファイル名は適宜調整すること)に作成したら、マウントしないようにできた。

SUBSYSTEMS=="usb", ATTRS{idVendor}=="19d2", ATTRS{idProduct}=="1557", 
  ENV{ID_FS_TYPE}=="iso9660|udf", ENV{UDISKS_IGNORE}="1"

なお、私がiV501をUSB接続する理由は以下である。

  • Wi-Fi接続でないから、PCでの通信が盗聴される可能性が減る(LTEについてはその限りではない)。
  • 電源をPCから取れるので、ACアダプタが不要になる。
  • (PCにWi-Fiインタフェースがないので、)Wi-Fi接続するための追加機器(ブリッジ)が不要になる。

注意: USB接続はiVideoのサポート対象外なので、自己責任で行うこと。

電池を入れずに起動できるか?

電池を入れずにPCのUSBポートにつなぐと、(全く動かない訳ではないが)惜しくも起動しない。Linuxでは、接続直後にUSBデバイスのconfigurationを設定する時にエラーになってしまって起動しない。

通信速度がものすごく遅い場合

月の終わりにレンタルを開始したら、前の人が多く使ったせいなのかキャリアの契約が始まってなかったのか、100kbpsくらいしか出なかった。私は交換してもらったが、同じルーター(実際にはSIM)でも、月が変わったら問題ない速度が出た。

Web API (2/5 19:28追加)

今のところ、goform_get_cmd_processでは以下の変数が取れることが分かっており、一部については内容を推測している(追記予定だが、自明なものが多い)。他にもありそうだが、管理webからアクセスされないので分からない。

  • modem_main_state
  • modem_init_complete
  • pin_status
  • blc_wan_mode
  • blc_wan_auto_mode
  • loginfo
  • fota_new_version_state
  • fota_current_upgrade_state
  • fota_upgrade_selector
  • network_provider
  • is_mandatory
  • sta_count
  • m_sta_count
  • signalbar
  • network_type
  • sub_network_type
  • ppp_status
  • rj45_state
  • EX_SSID1
  • sta_ip_status
  • EX_wifi_profile
  • m_ssid_enable
  • wifi_cur_state
  • SSID1
  • simcard_roam
  • lan_ipaddr
  • battery_charging
  • battery_vol_percent
  • battery_pers
  • spn_name_data
  • spn_b1_flag
  • spn_b2_flag
  • realtime_tx_bytes
  • realtime_rx_bytes
  • realtime_time
  • realtime_tx_thrpt
  • realtime_rx_thrpt
  • monthly_rx_bytes
  • monthly_tx_bytes
  • traffic_alined_delta
  • monthly_time
  • date_month
  • data_volume_limit_switch
  • data_volume_limit_size
  • data_volume_alert_percent
  • data_volume_limit_unit
  • roam_setting_option
  • upg_roam_switch
  • fota_package_already_download
  • ssid
  • dial_mode
  • ethwan_mode
  • default_wan_name
  • sms_received_flag
  • sts_received_flag
  • sms_unread_num
  • rssi
  • rscp
  • lte_rsrp
  • lan_station_list

 

まだ少ないが、他に分かったらまた投稿したい。

 

(2020/2/29 メールのLED、電池残量が少ない場合、webのSMSタブなどを更新)

  •   0
  •   0

注意 3か月くらいiVideoを使って何度かトラブルがあったが、SIM・ルーターの管理や障害対応が全く適切でないと感じた。更に、通信障害が起こっても、通信に関してはキャリア任せなのでトラブルシューティングができず、機材(SIM・ルーター)の交換しかできず、それも「様子見しろ」と言って渋るし、交換されるにしても届くのが数日後で、その間は障害はそのままなので、iVideoをメインに使うのはリスクが高過ぎることが分かった。その経験から、iVideoを重要な用途(例: 光回線の代わり)に使うことは全く推奨しない。

具体例については、「[悲報] 完全無線は時期尚早でござった。」を参照のこと。(2020/3/25 6:34)


数日前から使っているiVideoのモバイルルーターiV501。カイロの代わりになりそうで今の時期には助かるとかw、いろいろな謎や、たまに惜しいところや間抜けなところがあるものの、全体的には必要充分で問題ない感じだ。それどころか、今朝、期待すらしていなかった機能を発見して、大いに感心した。

切っ掛けは、iV501の通信データ量や電池の状態を見るのに管理webを開く時に、いちいちパスワードを入れる(ご丁寧にも、ある程度時間が経つと自動でログアウトされる)のが面倒なので(いや、認証すること自体はまったく正しくて、何も文句は言えない)、何とかならないか(要は「チートできないか」)と、通信の解析や検索をしたことだった。

認証以外に、間抜けな惜しいことに電池の残量が4種類程度のアイコン(下図右上)でしか分からないので、可能なら数値(%)で知りたかった(結局はできなさそうだ)。電波強度(下図上部"Soft Bank"の右)も同様だった(こっちは数値(RSSI)で得られた。図の下の方("Signal Strength")には数値が出ている)。

iV501の管理web

検索しても詳細な情報が出て来ないので、管理webにアクセス中のPC(Firefoxブラウザ)とiV501の通信をブラウザのDevelopper toolで見てみたら、頻繁に状態を取得していた(無駄に多い(毎秒くらい)ので、止めたくなったくらいだ)。それは以下のようなURL(API)だった(月の通信データ量と電池残量の取得を簡略化した例)。

http://(IPアドレス)/
  goform/goform_get_cmd_process?cmd=monthly_tx_bytes
  %2Cmonthly_rx_bytes%2Cbattery_pers&multi_data=1

結果は、以下のようにJSONで返って来る。

{"monthly_tx_bytes":"2929233487","monthly_rx_bytes":"1500560020",
  "battery_pers":"4"}

惜しいことに、このURLは上記の管理webを表示する前の認証を通してからでないと、値を返さないものが多い。それで、特徴的な"goform_get_cmd_process"で検索してみたら、他にも使われているらしく、いろいろなことが分かった。

まず、このURL(API)はGoAhead Embedded Web Serverという、組み込み用webサーバソフトで使われているようで、ZTE社の製品(例: MF823)で使われているようだ。iV501がZTE製なのか、ZTEの下請け製なのか、それ以外(ごにょごにょ?w)かは不明だが、本体内部に"MF833"という表記があったので、ZTEに関係しているように思う。ただ、ZTEにはMF833というUSB接続のモバイルルーターがあるが、それとiV501とは違うようだ(が、中身は同じなのかも知れないと思った: これがあとですごい発見に繋がるw)。

いくつかのページでは、上記のURL(API)でモバイルルーターの情報取得や制御を行っている。ただ、なかなか最初の認証の通し方が分からなかったのだが、Developper toolを探していたら、運良くgoform_set_cmd_processが認証を通している通信が見付かり、その通りにしたらようやくできた。以下のようなURL(API)で認証が通る。

http://(IPアドレス)/goform/goform_set_cmd_process?goformId=LOGIN
  &password=(BASE64エンコードしたパスワード)

実は、Developper toolで見付ける前に、別のサイトでも見付けて上記に近いことを試していたのだが、パスワードの指定を間違えていて(HTTPの要求ヘッダからコピーしたため、"ユーザー名:パスワード"をBASE64エンコードしたものを指定していた)通らなかった。

余談: 個人的には、こういうゆるい認証もどきは良くないと思う。というのは、一度認証されたあとしばらくは、どんなクライアント(自分以外も!)も全パスにしてしまうからだ。本来は、認証されたら、それを識別するトークンのようなものを返して、それを以後の要求に添付させてチェックすべきだろう。が、そもそもHTTP(SSL/TLSでない)だし、このwebに外部からはアクセスできないので、まあ、大きな問題ではないかと思う(でも、良く報道されるセキュリティ問題は、こういう手抜きから始まることは確かだ)。

そういえば、光の時に使っていたBuffaloのルーターもこういう認証方式で、面倒で嫌いだった。もしかしたら、同じサーバソフトなのかも知れない。

認証を通した後で、最初のURL(API)で情報を取得すればいい。

ここまで来たら、「あとはプログラムを書くだけ(面倒だなぁ。誰か頼むwww)」で話は終わるかと思ったのだが、MF833で検索した時に上記のUSB接続のルーターが出て来たので、ふと、「iV501のUSBをPCに挿したらどうなるかな?」と思い、「まあ、どうせ電源だけだよな・・・」とは思いつつも、ダメ元で挿してみた。

(2/3 17:36) 重い腰を上げて、プログラムを作ったw 指定した情報(変数)をiV501から取得するプログラムと、それをMunin(グラフィカルなPCの状態表示ツール)に入れるものを作った。以下のような感じ(下図の右側)で、MuninにiV501の月ごとの累積通信データ量(上)と通信速度(下)が表示できるようになった。

iV501の月ごとの累積通信データ量(上)と通信速度(下)をMuninで表示(右側, 左側はPCのグラフ)

比較のため、PCの同様なグラフを左側に載せた。スマフォの通信データ量は少ないので、PCとiV501のグラフはほとんど同じ形であるが、スマフォで動画を観まくったりアプリをダウンロードしまくると違いが出そうだ。

ちなみに、iV501からの情報取得プログラムの実行例を以下に示す。出力は、JSONかshで変数を設定するコマンド文字列のいずれかで出せるようにした。例では、iV501から電波強度(RSSI)、月の累計送信・受信データ量、電池の充電状態・残量を取得している(後述のバグのせいで、送信・受信データ量が入れ替わっている)。

./bin/iv501-vars.sh rssi monthly_tx_bytes monthly_rx_bytes 
  battery_charging battery_pers
monthly_rx_bytes="2797359595";monthly_tx_bytes="6248242876";
  battery_pers="4";battery_charging="0";rssi="-84";

余談: iV501にバグがあるようで、月の通信データ量の送信と受信が逆になって送られて来る。いかにも間抜けだけど、こういうのは僕もやるから全然許せるw なお、管理webでは送受信の合計(リンク先左下の"Used")しか出ないので、発覚しないのだろう。

そうしたら、とんでもないことになった。なんと、iV501がLTEのネットワークインタフェースになってしまったのだ! Linuxなのに挿すだけで使えたよ。ちなみに、ifconfigコマンドでは以下のような感じで出る。

enx00xxxxxxxxxx Link encap:Ethernet HWaddr 00:xx:xx:xx:xx:xx
inet addr:192.168.0.X Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::xxxx:xxxx:xxxx:xxxx/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:909876 errors:0 dropped:0 overruns:0 frame:0
TX packets:791882 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:615270891 (615.2 MB) TX bytes:266268613 (266.2 MB)

挿す前は、仮に認識したとしても、制御用のシリアル通信程度しか期待していなかった(それで欲しい情報が取れれば、充分ありがたかった)が、いきなりNW-IFとして使えるなんて、全く予想外だった。通信速度も問題なく出た(Wi-Fi接続同様、ダウンロードが20-50Mbpsだった)。

もちろん、これでしばらく試すことにしたが、問題なく使えるなら、iV501用の電源アダプタが不要になるのはもちろん、先日買ってPCに組み込んだばかりのTP-LinkのWi-Fiブリッジがお払い箱になる。組み込んだ苦労やお金が水の泡になるが、物が一気に二つも減るから、そっちの方が気分がいい。それに、ブリッジを内蔵しておけば、PCが(実質)Wi-Fi対応になるから いつか役立つことがあるだろう。

 

それにしても、iVideoはもったいない。こんないいもの(良く考えたら、僕が欲しかった物そのものだ)を、そうとは知らせずに出しているのだから。ただ、これが彼らの上手(うわて)なところなのかも知れない。「モバイルルーター」として出すなら、およそどんな機器でもSSIDとパスワードを入れるだけで簡単に接続できるし、モバイルルーターは世の中に多く出回っていてお客も慣れているだろうから、説明もサポートも手間要らずだ。実際、説明書は簡素な紙1枚だけだった。

一方、PCにUSBで繋げる(「ドングル」とか「モデム」のカテゴリになる)となると、途端にハードルが上がる。OSの種類・バージョン、ドライバ、OSメーカーの認証、コネクタ・ケーブル、電源容量などなど・・・ たとえPCに繋がっても安心はできない。OSのネットワークの設定・切り替えなどがいろいろありそうで、やっぱり面倒だろう。それ以外にも、管理webなんて公開したら更に問題が生じる契機が増えて、サポートの手間が激増するだろう。であれば、そういうのはないことにして、Wi-Fiだけで使ってもらうほうが得策だ。

(彼らが実際にそこまで考えたかどうかは分からないが、)うまいやり方に感心した。言ってみれば「ないない詐欺」だw

そして、日本は本当に中国・台湾(韓国はまだ分からない)に負けたのを実感した。製品もサービスのやり方も全く負けている。

物についてだけ考えても、これが日本製だったら、高くて(2倍以上はしそうだ)機能が多過ぎて(でも、ほとんど使わない)、難解な分厚いマニュアルが付いて来て、それを補完する「簡単マニュアル」なんてのまでありw(だったら、最初からそれだけにすればいいのに・・・)、しかも、結局はちゃんと動かないとか、(昔と違って)すぐ壊れるってことが多そうではないか。

なんて おそろしい子だw

  •   0
  •   0

先日一度キャンセルした後に注文した、USBのWi-Fi子機が届いた。Amazonに山ほどある、とても小さいWi-Fi子機である。送料無料で約300円だった。国内(関西)なのに発送の連絡から結構掛かったのと、そこに書かれていた伝票番号がデタラメな数字だったので、「ここもだめかなあ?」と、(怒る気にもならずに)半分諦めていたのだが、今日ちゃんと届いたので安心した。どうも、週末を挟むと結構遅れるようなのと、普通郵便で発送したので番号をテキトーに入れたらしい。

で、早速PCに挿してみたが、案の定、動きやしないw USBデバイスとしては認識しているのだが、意味不明(というか、分かろうとしていないw)なエラーが出てWi-Fiデバイスとしては動かなかった。Wi-FiチップはMediaTekのMT7601Uだ。

それで、検索したらいくつか出て来た。

  1. カーネルに含まれているドライバを修正する(2017, 一部を無効にする。sergio-codeのまとめが分かりやすい)。
  2. フリーのドライバを入れる(2016)。
  3. MediaTekのドライバを入れて修正する(2014)。

2, 3, 1の順に試したが、違うと思って最後まで試さなかった1が効いた。動き出して、子機の情報がifconfigコマンドにちゃんと出た時は、思わず「おっ! (動いたぞ)」となった。

結局、僕のLinux(Ubuntu 16 LTSベース)では基本的には挿せば動くはずなのだろうが、デバイスの個体差(ファームのバージョン?)の問題なのか、ドライバを修正しないと動かなかった。その修正が一体どういうものなのか、それでいいのかはまだ分からないので、追って調べたい。

それにしても、この修正を見つけた人は一体どうやって分かったのか、すごく不思議だ。ソースを見ながらカットアンドトライしたのだろうか?? 全く尊敬する。

一通り動作確認したところ、問題はなかった。ちゃんとスリープにも対応しているようだ(長時間のスリープは未確認)。すごく熱くなるという口コミがあったが、今のところは少し熱い程度だ。ただ、(頻繁に壊れて買い直すのは面倒なので)寿命を伸ばしたいので、延長ケーブルを使ってPC後部のファンの後ろに置いた。

通信速度は変わらず10Mbps(ダウンロード)だった。これで速くなるかと思っていたのだが、良く考えたら、LTEに繋げているのは従来と同じNexus 4だから速くなる訳がない。モバイルルーターが来るのを待つしかない(でも、本当に来るのか怪しい・・・)。

ちょっと気になる点は、以下である。

  • 動きはするものの、まだエラーが出ている。
    • 内容不明なので、元々のエラー同様にあとで調べたい。
  • nmcliコマンドで表示される接続(リンク)速度が54Mbpsで、仕様の最大値の150Mbpsよりかなり遅い。
    • nmcliコマンドの見方が悪いのか、nmcliの出力が正しくないのか、Nexusが遅いのか、PCの設定が悪いのか、それ以外か不明。手持ちのWi-Fiルータを起動すれば分かるので、あとで試したい。
    • 調べたら、54Mbpsというのは802.11gの速度なので、もしかしたら、PCかNexusで802.11nが有効になっていないのかも知れない。

これで、安定して動いてそこそこ長く使えるのなら、随分安くて小さくていい買い物だが、果たしてどうなるか?

(1/21 0:05) 早くも駄目だった。どうも、連続して送信するとデバイスが落ちてしまうようだ(受信は大丈夫な感じ)。安直に見えた修正はやっぱり駄目なのかも知れない。試行錯誤が要りそうだ。。。

(1/21 8:50) いろいろ試したが、どうも、まともに動かないようだ。上に書いた修正は、必要な処理がUSBの通信エラーになるからスキップするだけの対症療法(スキップした処理が行われないから、それで正常動作する方が不思議だ)なので、おそらく、Linuxのドライバ(タイミング?)が良くないのだろう※。でも、この子機はそれをデバッグするほど価値のある(高い)ものではないので、あっさり諦めて別のを注文した。今度はTP-LINKの700円くらいので、Linuxで動いたという情報はあるし、3年保証だから、壊れ易いとしても少しは安心だろう(でも、実際には交換するのは面倒だったりするが)。

※例えば、昔のカーネルではちゃんと動いていた・いるという情報もあるので、ドライバ(ベースは結構古い)とカーネルが合っていないのかも知れない。

まあ、安物買いの銭失いそのものだ。しょうもない。。。

 

とりあえず、これでPCを長時間スリープさせてもNexusの電池が切れることはなくなったし、Nexusを持ち出す時も電源を抜くだけで良くなった。あとは、モバイルルーターが届けば通信速度が高速になるはずだが、先週、「発送した」という連絡があったきり、そこに記載された番号を調べてもずっと準備中みたいな感じなので、なかなか予断が許されない。まあ、中国の郵便(China post)は溜まるまで保留されるらしいし、到着予定は1/31なので、今焦っても仕方ない。

(1/21 8:50) 仮に、無事モバイルルーターが届いても、今回の子機と同じようなことにならないかと結構心配になっている。まあ、その時はiVideoのルーターをレンタルしてしのいで、ゆっくりどうするか考えよう(おそらく、高い、ちゃんとした物を買うことになるのだろう)。

(1/21 19:50) モバイルルーターの件、「発送した」から一週間経っても配送状況が"Order generated/Shipping Label Created"(伝票が作成されただけ?)のまま変わらないので、しびれを切らして問い合わせたら、「通関がどうのこうので返送された」とか言う返事が返って来た。配送状況がずっと変わっていなかったのだから、そんなの嘘に決まっている(仮に本当に返送されたのなら、なぜ、聞かれて初めて連絡して来るのだ?)。でも、今回の子機のように、変な物を買ってお金を無駄にしてがっかりするよりは、ずっと良かった。

もう少ししたらiVideoのルーターをレンタルする。300GBで3300円と、僕には丁度いいのがうれしい。

 

ご注意: 外見が同じでも中身は別ということは大いにありそうなので、この情報はあくまでも一例として考えて下さい。実際、僕の買った物も、挿せば動くはずなのにそうではなかったです。購入される場合は、記載されたチップの番号で対応状況・口コミを確認することが重要です。

(1/21 8:50) 実際、今回失敗した物は、Realtekのチップを予想・期待していたのに実際はMediaTekでした。安い物にはいろいろなリスクがあります。

  •   1
  •   0

注意 3か月くらいiVideoを使って何度かトラブルがあったが、SIM・ルーターの管理や障害対応が全く適切でないと感じた。更に、通信障害が起こっても、通信に関してはキャリア任せなのでトラブルシューティングができず、機材(SIM・ルーター)の交換しかできず、それも「様子見しろ」と言って渋るし、交換されるにしても届くのが数日後で、その間は障害はそのままなので、iVideoをメインに使うのはリスクが高過ぎることが分かった。その経験から、iVideoを重要な用途(例: 光回線の代わり)に使うことは全く推奨しない。

具体例については、「[悲報] 完全無線は時期尚早でござった。」を参照のこと。(2020/3/25 6:34)


前回、iVideoの大容量LTEは「固定ルータにする」と書いたあとで、どうも夢が破れるのが気に入らなかったので、ちょっと試してみた。今、家でPCやスマフォ(AQUOS sense lite)とLTEを繋いでいるNexus 4を持って(もちろんAQUOSも)外に出てみた。

そうしたら、何ともいい感じなので結構驚いた。まあ、僕がセコいせいなのだが、AQUOSで契約しているプランのデータ量が500MB/月と少ないので、いつも外ではデータ量に気を遣わざるを得ず、Googleマップなんてどうしても必要な時だけにしていたし(でも、気のせいか、近頃はデータ量が少なくなったようだ)、Evernoteだって、開くたびに「データ量が増えるか?」とか思っていたし、Spotifyを使う時は低速モードにしていたのだが(注: 今日は使っていない)、そういう足枷がまったくなくなって、とんでもなく自由な気分、

好きなだけデータを使っていいんだぜ!!

という天の声が聞こえたのだ。

ちなみに、当然のことだが、外でもiVideoは全然問題なかった(ソフバン回線だから田舎にでも行けば話は変わるだろうが、ここら辺なら全く問題ない)。

でな訳で、方針を変えて、LTEは断然モバイルルータで繋ごうと思い、「ちょっと試す」ために、安いものを注文した。

正確には順序が違っていて、ルータを注文したのは昨日だが、細かい話は見逃して下さいw

また、PC用にもWi-Fi子機を注文した(これは、その前にUSBテザリングだとPCのスリープ時にNexusの電池が減るのを解消できるかと思ったのが大きい)。

 

なお、当然、「やっすいルーター」なんてヨドバシには売ってないのでw、先日退会したAmazonに再び入って、C国の怪しい店の中から少しは大丈夫そうなところを探して、3千円くらいのバッテリー内蔵のものを注文した。その前に、物(ルーター)自体についても、なかなかおもしろいと思ったUSB+Wi-Fi接続のものは「すごく熱くなる」とかいう口コミが多かったので、いろいろ比較・検討して、何となく大丈夫そうな気がするの(これはUSB接続ではなく、バッテリーが入っている)を見繕った。でも、もちろん実際にはどうか分からない。

Wi-Fi子機も同様だが、さっそくはまってしまった。注文して数日経っても発送するフシがないのでキャンセルした。なぜか、Amazonのwebでキャンセルしようとしてもできなかったので、Amazonのサポートに泣きついたら、意外なことに即座に状況を把握して対処してくれて、そういうところは日本よりいい・進んでいる(日本だったら、絶対に数日は掛かるね)と思ってしまった。なかなか難しい。

なお、Wi-Fi子機は、最初は本体約20円(+送料 200円)のを試したのだが、さすがに甘かったようなのでキャンセルして、今日、日本の会社の300円くらい(送料無料)のにした。日本の会社だからといって大丈夫な保証は全くないがw、口コミでは良さそうだった。さてどうなるか・・・ なんでAmazonはアドベンチャーゲームになるのかな?w

ちなみに、Linux対応については概ね大丈夫そうだ。ただ、苦労する可能性もありそうで、実際のところ、やってみないと分からない。そういうこともあって、駄目でも容易に諦められる「やっすいの」にした。なお、最初は当然国内の会社の製品を検討したのだが、「(熱くなって)すぐに壊れる」などの口コミが多かった(検討した全製品にあった。でも、なぜかヨドバシにはなかった)ので、「だったら本家本元のC国でいいや」ってことでAmazonにした。

 

まあ、細かい話はどうでも良くて、たった数時間で固定回線じゃないのはすごくいいことを実感した。当たり前のことなのかも知れないが、(特別に必要な場合を除いて、)もう光(固定回線)なんて時代遅れなんだね。

 

PS. これがうまく行けば、面倒ではあるけど、外でデータを使いそうな時にルーターも持つことにすれば、AQUOSをもっと安い回線(例: 完全従量制の0SIM)に換えて更に通信料を減らすこともできそうだ。ただ、面倒だからしなさそうではある。あと、0SIMはものすごく遅いようで、評判が悪過ぎる。でも、500MBまでは無料で、そういうのは他にないから考えたい気もする。 (1/16 6:56)

PS2. いいことを思い付いた。LTEのモバイルルーターをスマフォの裏にでも貼り付けておけば、ほとんどの場合で便利だ。今回注文した物のサイズは不明だが、できるだろうか? まあ、PCを停めずにちょっと外に出た時にPCの通信が停まるが、それほど大きな問題ではない気がする。 (1/16 12:16)

  •   0
  •   1

注意 3か月くらいiVideoを使って何度かトラブルがあったが、SIM・ルーターの管理や障害対応が全く適切でないと感じた。更に、通信障害が起こっても、通信に関してはキャリア任せなのでトラブルシューティングができず、機材(SIM・ルーター)の交換しかできず、それも「様子見しろ」と言って渋るし、交換されるにしても届くのが数日後で、その間は障害はそのままなので、iVideoをメインに使うのはリスクが高過ぎることが分かった。その経験から、iVideoを重要な用途(例: 光回線の代わり)に使うことは全く推奨しない。

具体例については、「[悲報] 完全無線は時期尚早でござった。」を参照のこと。(2020/3/25 6:34)


信じられないことに、1/10に届いてから今のところ何も問題ない。正確には問題はあるが、iVideoでなく こっちの問題だw

今までの通信データ量は測定する箇所やソフトによって異なるが、概ね5-8GBである。これなら、SIMの上限の900GB/月にはまず達しないだろう。良くある通信量による速度制限は3日で10GBなので(そういう制限があるとは書いてなかった)、それには掛かっていないから、隠れた制限の有無はまだ分からないが、少なくとも、説明にあった、他の人に迷惑を掛けるほどは使っていないようだ。参考までに、PCでの通信データ量と通信速度のグラフを載せる。

Spotifyを聴いている時は ほぼ一定の傾きでデータ量が増加している感じだ。たまにデータ量が急増する(速度のグラフが尖っている時)のはオンラインストレージに自動バックアップしているか、サーバをローカルにバックアップしている時である。なお、時々データ量が減るのは測定プログラムのバグである(テザリングのoff/onがうまく処理できていない)。

たまに通信速度を測ってみるが、安定の10Mbps程度だw 今日一回だけ、PCからのアクセスがすごく遅かったことがあったが、間違ってテザリングを断続させたせいかも知れない。また、動画はほとんど観ないが、特に問題なさそうだ。それから、突然通信が途切れることもない(ちょっと前に、PCのネットワークインタフェースが一瞬落ちて、すぐに繋がるということがあったが、頻発はしていないし、自動的に回復するから大きな問題はなさそうだ)。

そういう訳で、今までのところ、iVideoのSIMは、僕の日常的な使用に関しては何も問題がない。まあ、無線通信自体は大手キャリアのものだから当たり前なのかも知れないが、ここまで問題がないのには感心する。あと、ルータ代わりに使っている古いスマフォ(Nexus 4)も、過酷な使用に良く耐えているものだw

今までに見付かった問題を以下に挙げる。いずれも、iVideoには関係ないことである。

  • LTE通信用スマフォ(Nexus)の電池が切れる可能性
    • USBテザリングしているデスクトップPCをスリープさせると、USBに電源電圧は掛かっていてテザリングは切れないものの、なぜかNexusが充電しなくなってしまう。
    • Wi-Fiテザリングをしているせいか減る速度は速く(約12%/hだった)、約8時間で切れる計算だ。 → (1/13 3:14) その後、アプリを減らしてみたら約8%/hになって、約12時間まで伸びた。これくらいなら、切れる心配は少なそうだ。
    • いろいろ試したが対処できなかったので、何らかの理由でLTEルータを買わない時に改めて考えることにした。
    • 仮に電池が切れても、スリープ中なのでデスクトップPCは使っていないので、Wi-Fiテザリングをしているスマフォ(AQUOS sense lite)がモバイル通信になる程度で大きな問題はない。
  • スマフォ(AQUOS)からPCへのLAN経由の画像転送ができない。
    • (前回書いたもの) 対処は可能だが面倒なので、これも何らかの理由でLTEルータを買わない時に考えることにした。
  • 耳閉感や耳鳴りが再発
    • (これも前回書いたもの) どうも、中継用に使っていたPC(Vision-HT)のファンではなく、疲れや寝不足によるようだ。なかなか厄介だ。
  • 突然、PC(Linux)から通信ができなくなった。 (1/16 5:11追記)
    • Googleなどへのpingも通らない。一旦、LANを切断しても変わらなかった。
    • 「いよいよ速度制限が掛かってしまったか・・・」と思ったが、スマフォ(AQUOS)からは問題なかった。
      • → LTE接続用スマフォ(Nexus)のUSBテザリングをoff/onしたら直った。
      • やっぱり、スマフォをモバイルルータにするのは無理があるようで、ちゃんと使うならルータが必要だ。ちなみに、現時点でNexusでのモバイルの通信データ量は約20GBになっていた。

ルータの候補を探したが、余り高いものは買いたくないので、以下の2つしかない。

  • au Speed Wi-Fi HOME WHITE L01s HWS32SWA: 約8千円-1.2万円
  • NEC Aterm PA-HT100LN: 約1.2万円

通信速度と消費電力と小ささでNECが良さそうだ。速度はHWS32SWAのカタログ値は大きいが、WiMAXも合わせてCA(carrier aggregation)した場合なので、実際にはそれほど出ないと思う。そもそも、このSIMにすごい速さを期待するのは、八百屋で魚を求めるようなものだw あと、本当にあるとは思えないのだが、HWS32SWAのメーカーH社はスパイウェアが気になる。

モバイルルータも考えたが、Ethernetがないので不便だ。まあ、PCにWi-Fiの子機を付ければいいのだが、Linuxでちゃんと動く子機がなかなか少ないようで、失敗するのが嫌なのだ。それに、モバイルルータは内蔵電池の消耗が気になるので避けたい。

ルータを検討していて気付いてしまったのだが、固定ルータにすると、前回書いたようには外出時に簡単に持っていけない問題が発覚した。スマフォをルータにするのは安定性や耐久性(特に電池)や管理・保守の点で難点があるので、通常は固定ルータを使い、外に持ち出す時にはSIMを抜いてスマフォ(Nexus)に挿すのが良さそうだ。が、SIMのサイズが違うこともあるので、面倒でやらなそうだな・・・ 早くも夢は破れたw

てな訳で、来週末辺りまで問題がなければ、OCNを解約してそのまま光回線は終了にして、LTEルータを注文したい。今度は、届いてから「あっ!」ってことがないようにしたいwww

  •   0
  •   1

ここ数日、「例のトリッキーなやつ」(先日の投稿の、Spotifyアプリのログから音量正規化のための値(RG値)を抽出して正規化する方法)が諦めきれず、悪戦苦闘していた。何度も諦めたのだが、そのたびにアイデアが出て来てしまって再挑戦する羽目になり、今日は随分いい感じになったのたが、やっぱり駄目だった。

記念(または証拠)に、最良の状態での動作光景を載せる。画面左上はRG値取得用Spotifyアプリ、右上はミュート(上側)・ゲイン調整+リミッター(下側)用アンプ、左下はミニプレーヤー、中央から右下は再生用Spotifyアプリである。曲間でのアンプの設定の変化や、プレーヤーの切り替わり(アプリ下部の緑の帯)に着目されたい(もちろん、手で操作している訳ではないし、マウスなどを自動操作するツールを使っている訳でもない)。

Spotifyアプリから音量正規化のための値を抽出して音量正規化している画面

動作の流れは以下である。

  1. Spotifyアプリ(音量正規化: off)が再生を開始する(またはトラックが変わる)のを待つ。
  2. アンプでSpotifyアプリの出力をミュートする。
  3. プレーヤーをRG値取得用Spotifyアプリ(音量正規化: on)に切り替える。
  4. その曲のRG値が取得できるまで(再生して)待つ。
  5. アンプにRG値を元に計算したゲイン(増幅量)を設定する。
  6. プレーヤーを再生用Spotifyアプリに切り替える。
  7. 曲の先頭に戻る。
  8. アンプのミュートを解除する。
  9. 再生を開始する。

基本動作はできた※のだが、試しに少し(15分くらい)動かしていたら、RG値取得用アプリとSpotifyサーバの通信ができなくなってRG値が取れなくなってしまった。再生用アプリの動作は問題ないので、短時間(RG値取得用アプリに切り替わっている時間は約2秒)で切り替えるとうまく動かなくなってしまうのかも知れない。まあ、再生し始めたと思ったらすぐに切り替えるなんておかしな使い方を想定していないのはもっともだから、仕方ない。

※本方式での音量正規化処理自体は、全く問題なかった。性能(音量の揃い具合)はSpotifyアプリよりも良かった(とはいえ、大差ではない)。また、前回(「と思いきや」のあと)失敗した、プレビュー版のRG値とは異なる場合が多かったので、そちらには得体の知れない値が入っているようだ。

あと、不思議なことに、投稿用に動画を撮り直そうとして再度動かしてみたら、プレーヤー切り替えのタイミングがずれて※、曲間で余計な音(RG値取得中または曲の先頭に戻る前の音)が出るようになってしまった(上の動画はボツのテイクを投稿用に少し編集している。でも、ちゃんと動いていたのは確かで、夢や幻や捏造ではないw)。だから、SpotifyのアプリもWeb APIも、こういうタイムクリティカルな用途には無理があるようだ。

※アプリの切り替え時間(= RG値の取得・処理時間= 曲間)は最初は4秒くらいだったのだが、それでは遅過ぎるので(結構苦労して)高速化・最適化したら不安定になったようだ。元の遅い版ならもう少し安定なのだろうが、それでは気分が悪いw それどころか、最初は1秒以内にしたいくらいだった。

そもそも、(前回も書いたが、)これをやりたかった理由の一つはダイナミックレンジをなるべく減らしたくないことだが、再度計算してみたら、Spotifyの音量正規化のQuietモード(基準音量: -23LUFS)を使っても2ビットも落ちないことが分かった※ので、ポップ音楽でそこまでこだわる意味は全くないから無理する必要はない。

※先日の試算では、音量を-23LUFSにするのに23dB下げると考えたが、それは誤りで、SpotifyがRG値の計算に用いているReplayGainの基準音量は-14LUFSなので、(-14-(-23)=)9dB下げる程度であり、それは(9/6=)約1.5ビット相当である。

あと、RG値取得用アプリが駄目になる問題は、例えば、通信できなくなったらしばらく(数分?)待ってアプリを再起動すれば回復できるだろうが、たとえ自動的にするとしても、再起動されるまでは聴けなくなって気分が良くないし、音量正規化のon/off切り替え時にアプリを再起動したくないからこの方法にしようとしたのに、(再生用ではないけど)やっぱり再起動が要るのでは馬鹿らしい。それに、上に書いたように、タイミングが変動して安定して動かないのでは、とても実用にはならない。

そんな訳で、結果的には無駄なことをして疲れたが、いろいろ(細かい)発見があっておもしろかったせいか、余りがっかりはしていない。むしろ、事前の予想どおり駄目だったものの、基本的には目論見どおりに動作して満足したし、方が付いてせいせいしたw

 

最後に、開発中に分かったことなどを少し書く。

  • Spotifyアプリを外部から制御するにはWeb APIとDbusの2種類でできるが、プレーヤーを切り替えて使う場合はWeb APIだけを使った方がいい。Dbusで操作すると、どのプレーヤーが対象か分からなくなったり、意図したプレーヤーが操作されなかったり、プレーヤーの切り替えがうまくいかない場合がある。
    • Web APIはかなり遅い(数百ms/回)のでDbus(数十ms/回)で高速化したかったのだが、残念ながら駄目だった。
  • SpotifyのWeb APIを短時間に頻繁に使うとサーバがエラーを返すようだ(本文に書いたエラーもこれと同様)。HTTP 500なのでアクセス制限(rate limit)ではないようだが・・・
  • 更に、頻繁に使わなくても謎の動作をする場合がある。Dbusを使わなくてもおかしくなることがあるようだ。
  • 曲の開始直後に先頭にシークすると前の曲にジャンプしてしまうようで、少し待たないといけないようだ。
  • Linuxのサウンド系には謎の損失(音量低下)があるようで、どこかで4dBくらい音量が下がる。PulseAudio(実際にはALSA)からJACKに入るところか、JACKからサウンドカード(実際にはALSA)に出るところかと想像している。
    • ポップ音楽用の音量正規化の場合、目標の音量をReplayGainと同じ-14LUFSにしたので、理論上はアンプのゲインをRG値そのものにすれば良いはずなのだが、この損失を戻すためのゲイン(4.5dB)を加算した。
    • なお、クラシック音楽用ではその損失を加味して、4dB下げるだけで目標の音量(-23LUFS)になった。
  • (書いても誰も分からない気がするが、)本方式の制御プログラムでは、2つのイベント入力(SpotifyアプリのログとDbusのイベント)を混ぜて受信することで、両方ともタイムアウトなしの受信にすることができ、イベントに対するレスポンス時間の短縮と負荷の軽減ができた。でも、本文に書いたように、高速化したら逆効果だったようだw

 

PS. それにしても、昨日(12/29)までは年末という気がしなかったのだが、今日(12/30)になったら急に「今年ももう終わりか」モードになって、妙に慌ただしい気分になってしまった。そして、「年末なのにプログラミングなんてしている場合かっ?」て気もしたが、特に他にすることもないので問題ないw

  •   0
  •   0

Spotifyの音量正規化の改良では散々試行錯誤したが、ようやく自分が納得できるかたちで実現できた。もちろん、結果(性能)も全く問題なかった。音量(Integrated loudness)の値は全く問題なかったし、随分聴いてみたが、(自作とは全然違って、)我慢できないほどうるさい曲(演奏)※も小さ過ぎるものもなく、随分手を焼いていた曲もあっさり大丈夫だった。これなら気楽に聴いていられそうで、ようやく目的が達成できた感じだ。

※正確には、「うるさい」と感じる演奏はある。が、その音量値は全く異常でなかった。ということは、音作り(周波数分布や音質の悪さ? いわゆる「海苔波形」?)によるのか、僕との相性が悪い(音の好みや聴覚のラウドネス特性とのズレ?)のだと思う。実際、不思議なことに、アンプの音量を小さくしていても、いつもうるさく感じる演奏はやっぱりうるさく感じる。つまり、「うるさい」は音量が大きいだけではないということだ。まあ、語義からしても当たり前か。

以下に試行錯誤の経過や内容を書く。

前回の投稿ではSpotifyの音量正規化のNormalとQuietを手で切り替えて使うと書いた。そして、前回も書いたが、音量を揃える(増やす)ために増幅してもそれほど音質が劣化しないことが分かったので、その方法を詳しく検討した。基本的には、単に(ソフトの)アンプで増幅すればいいのだが、使う要素(アンプの種類)や増幅する量を最適にしようとしたのだ。

まず、以下を試した。増幅量は+11dB(-23LUFSを-12LUFSにしようとした)にした。

  • JACKのjack_mixerのボリューム:音は悪くない感じがした。 → その後、長時間聴いたら耳閉感が起こった。
  • PulseAudioのボリューム (Spotifyのsink-input):音が悪い感じがした。わずかに耳閉感が出た。

PulseAudioでの増幅で音質劣化がありそうだったので、何種類かの増幅量で歪率を測定したが、オーバーフロー(0dBを超える)しなければ(+15dBくらいまで)は問題なさそうだった。それで、実際の曲で試したら、ポップ音楽でも意外にダイナミックレンジが広いようで、+9dBでも簡単にオーバーフローした。

それで、リミッターでオーバーフローしないようにすることにした。PulseAudioで増幅してオーバーフローすると、その時点で歪んでしまうので、あとにリミッターを入れても無意味なので、JACKのアンプ+リミッターの構成にすることにした。リミッターにもいくつかの種類があり、以下でオーバーフローさせて試したが、いいものは少なく、結局、Fast Lookahead limiterを使うことにした。これには入力にゲインがあって、それがアンプの役割をするので丁度良かった。

  • Fast Lookahead limiter: 一番いい感じ。過大入力でも、自然な音で0dBを超えないように制限される。
  • Wave Shaper (Sine-Based): 過大入力(例: +17dB)で音が変わる(歪む)。
  • Simple Limiter (Peak Env. Track.): 過大入力(例: +17dB)で「ワウワウ」になる。
  • Calf Sound GearのCalf Stereo Tools: 最初は良かったが、長く聴いたら耳閉感が起こった。
    • 後述のNon Mixerにした時に、バイパス機能とSoftClip(リミッター)があるので試した。

それから、Spotifyの音だけを増幅したいので、SpotifyのJACKへの出力を独立にし、更に、ポップ音楽用とクラシック音楽用で増幅をon/offする必要がある。

その前に、いつも評価用に使っている曲をSpotifyの正規化(Quiet)+増幅(+9dB)で試したところ、殆どのポップ音楽は問題なかったが、"Speak to me"は駄目で、Normalと同様な不自然さがあった。原因を調べたら、前回の投稿の付録に詳しく書いたが、オーバーフローがリミッターでカットされる時間が長いためだと分かった。それで、増幅量を+6dBに減らし、リミッターの回復時間を長く(2秒)にすることで不自然さを緩和した。回復時間を"Speak to me"の鼓動の周期より長くすれば、ずっと音量が下がったままになるので、不自然さが緩和されるのだろう。完璧ではないが、"Speak to me"のような曲は例外的だから許容できると考えた。ただ、他の曲が不自然になるかも知れないので、その時に調整したい(今のところは問題ない)。

結局、以下の3つのモードを作ることにした。

ポップ向けでの増幅量について: 通常のReplayGainで正規化する(あるいは、0dBまで目一杯出す)他のプレーヤー(具体的にはgmusicbrowser, GMB)と音量を揃えるにはなるべく上げる方がいいが、前述したオーバーフローによる劣化も嫌なので、試行錯誤(勘?w)で決めた。+7dBだと、SpotifyのQuietモードでの基準音量 -23LUFSを-16LUFSまで上げることが期待できる(当初は+10dBして-13LUFSくらいにしたかったが、やり過ぎのようだ)。

3つのモードはミニプレーヤーのボタン(右端の"Sp", "S", "-")で切り替える。音量正規化の有無はSpotifyを再起動すればいいが(とはいえ、重いから避けたかったが、それ以外に方法がないので仕方ない)、JACKのアンプで外部から制御できるものがなかった(後述するように、実はそうではないが、当時はそう思っていた)ので、増幅の有無の切り替えが困難だった。それで、接続(配線)を変えることにした。簡単に書くと、以下のように切り替える。

  • 増幅あり: Spotify → アンプ → ミキサー → 補正用イコライザ → 出力
  • 増幅なし: Spotify → ミキサー → 補正用イコライザ → 出力

なお、なるべくSpotifyを再起動しないで済むように、右クリックで音量正規化モードの切り替えを逆順にできるようにしたのだが、順番を覚えていないためにやっぱり再起動になる羽目になるので、マウスオーバーでガイドを出すようにした。

なお、プログラム(xdotool)でリミッター(アンプも兼ねる)のEnableボタン(中央付近)を押すことでも、増幅の有無の切り替えが可能なので試してみたのだが、勝手にマウスが動くと(その後自動で元に戻しても)結構ストレスに感じるし、その時の操作状態によっては誤動作・操作することもあるので止めた。

その後、モード切替のたびに接続(配線)を変えるのは全然スマートでないし、遅いし、JACKサーバへの負荷が重そう(頻繁に繰り返すとおかしくなりそうな気がした)なので、避けられないか考えた。それで、以下の2種類を順に試した。

  1. OSC(Open Sound Control)という仕組みで外部プログラムから制御可能な、Non Mixer(エフェクタも入れられるミキサー)を使い、リミッターの増幅量を変える。
    • Non Mixerはエフェクタのon/off(Bypass)を外部プログラムから制御できないので、増幅なしの場合にはリミッターの増幅量を0dBにすることで、offの状態にした。
    • この方法には実用上は何も問題がなく、充分良かったのだが、微妙に気に入らないために別の方法を探して、次の項のjack-rackになった。例えば、以下が気に入らなかった。まあ、車で言えばトヨタのように、「ソリが合わない」ってやつだろうかw まあ、jack-rackが駄目なら戻ればいい。
      • 外部からBypassが制御できない。ゲインでもできるけど、何か直接的でない。
      • 大げさ: ウインドウが無駄に大きいけど小さくできない(確か、一番幅を狭くした状態がこれ)。
      • 名前が悪い(結構真面目に良くない)。「おフランス」なのだろうか?
  2. MIDIでjack-rack(エフェクタを入れるソフト)を外部プログラムから制御し、リミッターのon/offを切り替える。
    • 試行錯誤の結果(以前試した記録が役に立った)、MIDIを使う方法が分かり、どうにかjack-rackも制御できるようになったので、リミッターのon/offが外部から制御できるようになった(のEnableボタンを押すのと同じ効果)。
      • ただし、ちょっとしたバグがあり、jack-rackの起動後にMIDI設定のダイアログが出てしまうが、仕方ない(これを自動で閉じるようにしたら動作がおかしくなってしまったので、手で閉じることにしている)。
      • ↑面倒だし目障りなので、xdotoolで"OK"ボタンを押すようにして自動で閉じるようにした。ただ、ウインドウサイズが変わると予期せぬ事態が起こりそうだ。 (18:19)

MIDIについての特記事項を以下に列挙する。

  • JACKサーバ: MIDIドライバ(midi-driver)に"seq"を指定する。
    • 上記設定をすればa2j_control(a2jmidid)は不要と思われる。
  • MIDIの配線: 当然ながら、JACKで、外(ALSA?)からのMIDI情報の出口(僕の環境では"Midi-Through:midi/playback_1")と制御対象の要素(jack-rack)を接続しておく(図左側の赤線)。
  • MIDI制御情報の送信: sendmidiコマンドを利用した。他にもあるが、僕には一番使いやすかった。
    • 実行例: sendmidi dev "Midi Through Port-0" ch 1 cc 0 0: (僕の環境・設定において)jack-rackの"Enable"をoffにする。
      • 注: 上記MIDIデバイス名はJACKでのもの(一つ上の項に書いた)とは異なる(ALSAのもの?)。sendmidi listコマンドで名前を確認すること。
  • jack-rackの設定: 制御したい要素(例: ボタン)上で右クリックすると設定ダイアログが出るので、そこにチャネル番号(sendmidiのchに指定する番号)とコントローラー番号(sendmidiのccに指定する番号。正式な名称は不明)を設定する。
    • この方法がなかなか分からなくて諦めていたのだが、jack-rackのgithubのページでようやく分かった。
    • Enableについては、設定値に127以上を指定しないとEnable状態にならない(Disable状態にする時は0でいい)ので、0と256を指定することにした。
    • あとで使うかも知れないので、Input gainとWet/dryも設定できるようにした。
  • どうしてか、(音と違って)JACKでの正式なMIDIのポート名は"system:midi_playback_1"のような分かりにくいものになり、起動のたびに番号が変わる感じで(要確認: 思い違いかも知れない ← クライアント(jack-rack)側の名前の番号は、起動順序で変わるのかも知れない)、自動で配線を保存・復元する機能がうまく動かなかった。それで、現在使っているMIDIの線は1本と少ないので、自動保存・復元の対象にせずにJACKの起動スクリプトで個別に配線することにした。
    • JACKの設定などで直るのかも知れない。
    • ↑JACKの設定ではなく自動で割り振られるようなので、JACKサーバ起動時にMIDIポート名の変換テーブルを作り、接続の自動保存時に、そのテーブルを元に、クライアントの起動順序で変わらないポート名(alias)に変換して保存するようにした(変換後の名前でも接続できるので、復元は問題ない)。 (12/23 22:42)
  • MIDIではデバイスの設定状態を取得することができない(標準的な方法がない)ので、アンプの状態は常に「上書き」する(現在の状態と比較するようなことは行わない)ことにし、設定後に状態をファイルに保存しておき、ミニプレーヤー(minisp)の起動時に保存された状態を再設定することにした。
    •  (ソフトの)MIDIは高速だしデータ量も少ないから、これで大きな問題はなさそうだ(世の中の電子楽器は基本はそうなのだろう)。
    • また、再生停止中にJACKサーバが再起動することもあるので、再生開始時にそれを検出したら(サーバの起動後に起動時刻をファイルに記録しておく)保存された状態を再設定することにした。上で「問題ない」と書きつつも、毎回無意味に設定するのは気分が悪いので、ここでは無駄な設定を省くようにしたw

それから、Spotifyの音量正規化(改良版)の性能を自作の方式と比較した結果を書く。双方で共通する38曲(演奏)について比較した。

判定条件

  • 音量の許容範囲: 基準(中心)から±2LUFS以内 (幅: 4 LUFS)
    • 音量(Integrated loudness)が上記許容範囲内なら問題なし(○)とする。
    • 問題なしの外側2 LUFSを可(△)とし、可の外側を不可(×)とする。
    • 下記の「偏差」は、音量が許容範囲の外側(○以外)に出た量である。

Spotify (Quietモード)+増幅 (ポップ音楽用: "Sp")

  • 設定
    • 基準音量: -16 LUFS
    • 音量の許容範囲: -18 .. -14 LUFS
  • 結果
    • 範囲内(○): 35曲 (92%)
    • 可(△): 3曲 (7.9%)
    • 不可(×): 0曲 (0%)
    • 合計: 38曲
  • 統計量
    • 音量の平均: -15.8 LUFS
    • 音量の標準偏差: 1.39
    • 偏差の平均: 0.1 LUFS
    • 偏差の標準偏差: 0.39

自作の方式 (ポップ音楽用: "Pk")

  • 設定
    • 基準音量: -20 LUFS
    • 音量の許容範囲: -22 .. -18 LUFS
  • 結果
    • 範囲内(○): 25曲 (61%)
    • 可(△): 9曲 (22%)
    • 不可(×): 7曲 (17%)
    • 合計: 41曲
  • 統計量
    • 音量の平均: -19.5 LUFS
    • 音量の標準偏差: 2.80
    • 偏差の平均: 0.74 LUFS
    • 偏差の標準偏差: 1.54

はっきり言って完敗である。Spotifyには不可(×)の曲がまったくなかったのには感心する。しかも、範囲内(○)に収まっている率が1.5倍と高く、音量のばらつき(音量の標準偏差)は半分以下、偏差の平均は1/7以下である。(数値的には)充分に音量が揃っていると言える。

ただ、負け惜しみではあるが、Spotifyは必要なデータを使って「普通に音量正規化(ReplayGain)をしている」のだから、良くて当たり前だとは思う。が、自作で情報(RG値)が不足した状態でいくら頑張っても勝ち目はないし、意味がないことは確かだ。

最後に、今回分かったことなどを列挙する。

  • クラシック音楽は予想以上にダイナミックレンジが広い。例: チェロの演奏(「無伴奏チェロ」 "Suite No. 5 in C Minor BWV 1011: V. Gavottes I & II")でもピークが平均値+約18dBまである。
  • 思い込みかも知れないが、日本のポップ音楽は比較的音量が揃っている。正規化後の音量が申し合わせたかのように基準値付近だった。国民性?
  • どうしてか、Calf Studio Gear(JACK Audioのエフェクタのスイート)はやっぱり駄目だった。リミッターですら耳閉感が起こる。根本的に作りが悪いのだろうか? でも、誰も文句を言っていないようだから、僕との相性なのか・・・
  • 少しだけでもMIDIの使い方が分かったのは収穫だ。演奏はしないが、JACKの要素の制御に使えるのが便利だ。
  • 同様に、今回は使わないことになったが、OSCも制御に便利そうだ。ただ、手間を掛けてそういう新しいのを作らずに、Dbusを使えば良かったのにとも思う・・・

これにて音量正規化問題は一旦終了!

一段落して、心置きなく気楽に音楽が聴ける。

 

と思いきや、、、毎度のことながら、そうは問屋が卸さなかったwww

昨夜、複雑なために一旦諦めたトリッキーなSpotifyの音量正規化用の値(以下、RG値)取得の方法を、なるべく簡単に実現するにはどうしたらいいかなどと考えながらSpotifyのログを眺めていたら、思わぬ展開になった。すごく簡単に取れるかも知れないことが分かったのだ。

RG値はSpotifyアプリのログに出ることは分かっていたが、音量正規化をonにしないと出ないし、その仕様がいつなくなるかも知れないのだが、SpotifyのWeb APIのGet a Trackなどで取れるプレビュー(試聴)用のMP3ファイルに入っていたのだ。全くコロンブスの卵というか、灯台下暗しだ。

その前に、RG値も入っていると思われる、ヘッダ部("head file")取得用URLがログから分かり、その中身はBase64エンコードされたOggだったので、「もしや!?」と思ったのだが、曲のデータ同様中身が暗号化されていてお手上げだった。

ただ、プレビュー用のファイルを普通にsoxiやexiftoolやプレーヤーで情報を表示してもなぜかRG値(例: REPLAYGAIN_TRACK_GAIN)が出ないので諦め掛けたのだが、ffprobeでは"Side data"として出た。だから、通常のMP3での格納方法ではないのかも知れない。あるいは、僕がMP3に詳しくないだけか?

↑調べたら、MP3のRG値は「LAMEタグ」というものに入るようだ(MP3の標準タグ(ID3v2?)に入らないのかは分からない)。eyeD3というコマンドに--lametagというオプションを指定すると見られる(そうしないと見られない!)。あ、lameはフリーのMP3エンコーダだから、LAMEタグという名前からして、それが独自に付けているようだ。ということは、入ってないものも、将来なくなる可能性もありそうだ。MP3は随分使われているのに、RG値すら標準で入れられないのだとしたら、なかなか面妖だなあ。。。 (18:51)

それで、その値が正しいかを確認するため、数曲で全体(全曲)とプレビュー版のRG値(track gain)を比べた。なお、全体のRG値はSpotifyアプリのログから抽出した。

  • 夏の扉
    • 全体: -8.71 dB
    • プレビュー版: -9.30 dB
    • 差: -0.59 dB
  • どうにもとまらない
    • 全体: -8.64 dB
    • プレビュー版: -9.10 dB
    • 差: -0.46dB
  • Speak to me
    • 全体: +13.49 dB
    • プレビュー版: +14.10 dB
    • 差: +0.61dB
  • Born to be wild
    • 全体:-3.64 dB
    • プレビュー版: -3.40 dB
    • 差: +0.24 dB

一見、全体とプレビュー版で随分値が違っていたのでがっかりし掛けたが、差を求めたら1dB未満(0.5dB前後?)なので、使えるかも知れないと考えた。

最初はRG値の差は圧縮率の違い(全体: 160kbps, プレビュー: 96kbps)によるものだと思ったが、その後、プレビュー版は先頭の30秒だけで、RG値もその部分のものであるために異なっているのではないかという懸念が生じた。それで、先頭の音量は小さく、後半に大きくなる曲("Stairway to heaven")で確認したら、プレビュー版のRG値も全体ものらしいことが分かった。: プレビュー版のRG値は全体の値とほぼ同じで、更に、手持ちのもの(マスタリングが異なるかも知れない)の先頭を切り出してRG値を求めたら、(先頭は音量が小さいため、)プレビュー版や全体より随分大きな値になった。以下にそれらの値を示す。

  • Spotify
    • 全体: -5.26 dB
    • プレビュー版: -5.0 dB
  • 手持ちの曲の先頭(30秒)の切り出し: +5.2dB (GMBで求めた)

実際、手持ちの演奏のラウドネス(Integrated loudnessをebur128コマンドで求めた)は13.3LUFS違っていた。

  • 全体: -11.1 LUFS
  • 曲の先頭(30秒): -24.4 LUFS

念のため波形を比較すると、確かに先頭と全体の平均音量は10dBくらい違っていそうだから、きっと大丈夫だ。

"Stairway to heaven"の振幅: 上: 全体, 下: 先頭30秒 (縦軸はdB)

実際、Spotifyの立場で考えると、プレビューを提供するためだけに全部の曲のRG値を計算し直すのは馬鹿らしいし、プレビュー版の再生時に正規化するとしたら(実際にはしないと思う)、全体のRG値でする方が本来の雰囲気に近く、「試聴」の意図に合うから、全体のRG値を入れている(実際には全体の値を捨てずに残しているだけ?)のは腑に落ちる。想像だが、この値はレーベルから提供された試聴用ファイルに入っているものなのではないだろうか? (音源提供者向けの案内を調べれば分かるかも知れない)

プレビュー版内のRG値を使う場合には、以下のような手順で「普通の」(自分の好きな基準音量に合わせられ、Spotifyアプリのリミッターを回避する)音量正規化ができそうだ。

  1. Spotifyアプリが再生開始するのを待つ。
  2. API: Get a Trackを使い、プレビュー版を取得する。
    • Get a trackのpreview_url要素より。
  3. プレビュー版のファイル(MP3)からtrack gainを抽出する。
    • ffprobeを使う (exiftoolやsoxiでは出ない)
  4. 音量正規化処理を行う。
    • 抽出したtrack gainに従って、音量補正値をアンプに設定する。
      • 基本的にはtrack gain(dB)そのものをを設定すればいいが、オーバーフローを回避するために、適切にオフセットする(下げる)必要がある。

あとは作るだけ。だが、ちょっと疲れた。それに、寒いしお腹空いたしw

 

と書いたところで、思わぬ落とし穴に気付いた。: すべての曲に、あるいは、今後もずっと、プレビュー版にRG値が入っているか疑問だ。入ってない曲があったり、いつかなくなる可能性がありそうだ。上に書いたように、この値は使われることがないだろうし、意図的に捨てていないからあるだけで、Spotifyのサービスの仕様ではないからだ。

そうなっても、(今までのように、)いくらでも回避策は考え付くだろうが、結局、堂々巡りになりそうな感じだ。それだったら、(音質などが完璧ではないものの、)気楽に聴ける今の状態で満足するのが一番得策な気はするが・・・ うーむ。 まあ、興味本位で「お遊び」でやるなら ありかな(いや、全部遊びだがw)。

↑イマココ

(12/25 12:41) 「プレビュー版のRG値で正規化」をちょっと試してみた。結論は、やっぱり駄目だった。以下に理由を書く。

  • 予想どおり、RG値が入ってない曲がある。確率は5%程度ではあるが、少なくない。
  • 更に、RG値がおかしい曲もあった。こちらは10%程度と多い。
    • 数曲について、Spotifyアプリのログに出る全体(正式版)のRG値とプレビュー版のRG値を比較したところ、正規化後の音量が駄目だったものは大きく異なっていた。
    • 逆に、プレビュー版のRG値で正規化でも問題ない場合は近かった。
    • 当然ながら、全体のRG値で正規化した音量を計算したら基準範囲内だったので、問題なさそうだった。

どちらも致命的だ。評価用プレイリスト(ポップ・クラシック合計約90曲)で試したところ、ポップ音楽はまあまあだったが、クラシック音楽は惨憺たる結果だった。うまく行くものもあるから、その曲のプレビューのRG値が良くないのだが、どうしてそうなのかは分からない。プレビュー部分だけのRG値が入っているとか、元の版が違う(プレビュー用は初期のマスタリングなど?)とか、テキトーに計算したとかだろうか。いくら原因が分かっても、プレビュー自体すらなくてもいいような状態でSpotifyは全く保証していないので、対処してもらえる訳がない。

プレビューですらこんなことでは、以前書いた、ログからRG値を抽出する「トリッキーな方法」なんて余計駄目だろう。

いずれにしても、結果としてはイマイチだった。これがうまく行ったらすごくいいと思うが、やっぱり問屋が卸してくれなかった・・・ まあ、作るのはそれほど大変でなく、いつものようにおもしろかったからいいや。

そういう訳で、今は元の状態に戻して、「気楽に聴ける」状態になった(この音量正規化が破綻しないのには本当に感心するw)。これを試した一番の理由の、正規化をon/offする時のSpotifyの再起動を回避する件については、別の方法を考えたい。

一応、設定画面を開かずに、外部から音量正規化をon/offする方法はないかSpotifyに聞いたが、「ない」とのことだった。まあ、それは仕方ない。きっと、かなりニッチな要望なのだろう・・・ (12/25 15:38)

(とりあえずは、)本当に一件落着■

 

(題の漢字は、各自自由にご想像下さいw)

  •   0
  •   0

どっかの国の政府とか軍隊みたいに、勝算がないのに精神論(利権も?)で金・労力を投入して無理な行軍を延々と続けて、最後に、さまざまな言い訳をしながら形式上は「成功」などと発表してドヤ顔して(それどころか、首謀者が逃亡・知らん顔して、)煙に巻くのは愚の骨頂だ。駄目なものはなるべく早く気付いて切る(少なくとも、再検討や方向転換する)のが重要だ。

試行錯誤しているSpotifyの音量正規化処理の改良だが、ポップ音楽モードがそこそこ うまく行って、クラシック音楽モードも調整して目処が立ったものの、今朝寝ながら思い付いた(気付いた)。Spotifyアプリの(標準の)音量正規化機能がどのくらいのものなのか、それと今回の自作の方式にどのくらいの差があるのか確認しようと。特に、曲の特徴量のデータが誤っているのではないかというくらい大音量になるいくつかの曲(例: "Take My Breath Away", "Catacombae")は、Spotifyアプリの音量正規化ではどうなるのか興味があった。

やってみたら、多くの収穫があった。

  • Spotifyアプリの音量正規化の性能はいい。自作の方式よりずっと音量が揃う。ポップ音楽での音量幅(ラウドネスの不揃い度)は、自作の方式では、(試した数曲の音量の範囲が広かったとはいえ、)おかしい音量になる曲を除いても、目分量でSpotifyの2倍(LUFS値の幅)くらいだった。おかしい音量になる曲を含めれば数倍になる。
  • Spotifyアプリの音量正規化のうち、Quietモードでは、Normalモードと違い、すごく静かな曲(例: "Speak to me")を不自然にしてしまうコンプレッサー(のような処理)が働かないようだった。
  • Spotifyアプリの音量正規化用の値は、ログやコンソール出力から取得できる。ただし、音量正規化をonにしていないと出ない。

Spotifyアプリの結果を聴いたら悔しいくらいだった(上記の困った曲が何の問題もない音量で出ていた)。悔しいけれど、結局、自作の方式でいくら頑張っても苦労ばかりで余りメリットはなさそうだ(そもそも、目的はそこにない)。それよりは、Spotifyアプリの音量正規化をうまく使えばいい。

一番手軽なのは、音量正規化をする場合は常にQuietモードを使うことだ。これなら、ポップ音楽でもクラシック音楽でも切り替え不要で、静かな曲でも音が不自然になることはなさそうだ。ただ、目標音量が-23LUFS程度と小さいので、もったいない気がする。特に、ポップ音楽では、もっと音量を上げてSN比を向上させたりダイナミックレンジを減らさないようにできる(だからNormalモードを使いたいのだが、例のコンプレッサーが邪魔だ・・・)。が、そもそも、音量正規化して聴くというのは、BGMのように気軽に聴いている時であり、その時にSNだのダイナミックレンジだのと言っても無意味だ。逆に、真剣に聴く時には音量正規化を使わないから、これで問題ないとも言える。

少し前に試行錯誤中に知ったのだが、Spotifyアプリの音量正規化はトラックモードとアルバムモードを自動で切り替える(アルバム再生時は後者になる)とのことなので、自作しようと思った切っ掛けの一つの、アルバムモードがないことも解決できた(この機能は後から追加されたのか、最初からあったが公表されていなかったのか)。そういう点でも、特にモバイルなどで切り替えずに使いたいなら、Quietモードにしておけば不便はない(まあ、モバイルでは周囲が騒がしいので、すごく静かな曲が不自然でも問題なさそうだから、Normalでもいいとも言える)。

ただ、Quietモードのもう一つの問題は、音量が小さいので他のプレーヤー(僕の場合は、gmusicplayer, GMB)と合わないことだ。これは結構厄介だ。Spotify(音量正規化)からGMBに切り替えた途端に大音量(約+11dB, 3.5倍)になるので、常に注意が要るし(大抵忘れて驚くw)、アンプの音量調整が煩雑だ。アンプの音量を変える代わりに他のプレーヤーの音量を下げる手もあるが、やっぱり「もったいない」から避けたい。逆に、Spotifyアプリの音量を後で大きくして合わせる手もあるが、一旦小さくしているのを増幅すると音質が劣化するから嫌だ。

書いた後で気付いたが、小さくしたのを増幅すると音質が劣化するというのは本当だろうか? (アナログでなく)ディジタルなので、増幅でオーバーフローしない限り、小さくした時より劣化することはない気がして来た。あとで検討したい。 ← データフォーマットにも関係ありそうだ。 → 検討結果を付録に記載した。 (12/19)

調べると、-23LUFSというのはEUの放送の基準レベル、あるいは、クラシック音楽向けだそうで(USや日本の放送は-24LUFS)、それに合わせるのは悪くないとは思うものの、自分の閉じた環境なのに一律に低く合わせるのはやっぱりおかしい気がする(実際、SpotifyやYouTubeの基準は-14, -13LUFSと、-23LUFSよりかなり大きい)。

以下に、候補とそれぞれの欠点をまとめる。

  • 自作の音量正規化
    • 音量を揃える能力がSpotifyより低い。
    • 全然揃わない曲がある。
    • 原因: Spotifyから音量正規化のための値(ReplayGain)が取れないので、音響的特徴量から推測しているため。
  • Spotifyの音量正規化: Quietモードのみ
    • ポップ音楽でダイナミックレンジがもったいない。
    • 音量が小さいので、音質が劣化する?
    • 他のプレーヤーと音量が揃わないので不便。 → 増幅すると音質が劣化する(要確認 → 検討結果を付録に記載した。 (12/19))。
    • 原因: Quietモードは音量が小さいため。
  • Spotifyの音量正規化: Normal, Quietモードを切り替える。
    • Normalで不自然になる曲(静かなもの)がある。
    • 原因: Spotifyアプリの処理(コンプレッサー?)が入ることがあるため。

上述のとおり、自作の音量正規化が駄目なのはSpotifyからReplayGainが取れないためなのだが、どうにかして取る方法はないかと試行錯誤していたら、思わぬことで取れた! 既に書いては居るが、アプリのログやコンソール出力に表示されるのだ。以下に"Speak to me"での例を示す。太字がトラックのReplayGainである。

02:05:55.089 I [libvorbis_ogg_decompressor.cpp:401] track gain: (13.25Db), track peak: (0.409425dB), album gain: (-5.09dB), album peak: (1.02865dB), normalization: trackgain

ちなみに、それらはGMBでの同じ曲(同じマスターと思われる)でのReplayGainの値と概ね合っていた。

なお、peakの単位が"dB"と書いてあるが、誤りであろう(正しくは単位なし)。同じく"Db"もtypoだろう。ここら辺は そうなる状況が分かる。つい指が動いたとか、余計にコピペしたとか。「(見ると気になるけど、)デバッグ用だからまあいいか」、みたいなw

それで、自作の音量正規化にSpotifyのReplayGain(以下、"RG")値を使う(苦肉の)策を考えた。理論的には、RG値取得用と再生用の2つのSpotifyアプリを使えばできそうだ。以下に手順概要を示す。

  1. 再生用Spotifyアプリを音量正規化offにする。
  2. RG値取得用Spotifyアプリをログまたはコンソール出力ありで起動する。
  3. RG取得用Spotifyアプリの音量正規化をon(NormalまたはQuiet)、音量=0(-∞ dB)にする。
  4. RG取得用Spotifyアプリで再生開始する。
  5. ログまたはコンソール出力からRG値を取る。(すぐに出るはず)
  6. RG取得用Spotifyアプリを一時停止する。
  7. 得られたRG値で再生用Spotifyアプリの音量を調整する。(現在の自作と同じ方法)
  8. Spotify APIを使い、有効なプレーヤ(デバイス)を再生用Spotifyアプリに切り替える。
  9. 再生用Spotifyアプリで最初から再生開始する。

ちょっと手で試して、やればできそうな気はしたが、(すっかり忘れて居た)昔のGoogle play musicの時(→ )と同様に、余りにもトリッキーで嫌になるくらいだ。また、アプリが2個なのでメモリも2倍食いそうなのも嫌だ。そもそも、ログにRG値が表示されるのは仕様でもなんでもないので、出なくなったら元の木阿弥だ。。。

だから、やっぱり筋が悪い。

そして、作るのは面倒だw

それで、とりあえずは、Spotifyの音量正規化機能を使うことにし、ポップ音楽とクラシック音楽でNormal(ポップ)とQuiet(クラシック)を切り替えて使ってみて、Normalでどのくらい不自然な曲があるかで判断することにした。Normalで駄目な曲は(DBに記録しておいて)自動でQuietに切り替える手が考えられるし、多かったらQuietだけ使うとか、上のトリッキーな手を使うことも考えられる。

それにしても、「とりあえず」のNormalとQuietを手で切り替えて使うにも自作ミニプレーヤー(minisp)に多少の変更が要るので、「ちょっと疲れたから、まあ明日にするか・・・」と一休みしているw ← イマココ

相変わらず寄り道が多く、先は長いw

 

(12/19 16:40) 付録: (デジタルで)増幅すると音質が劣化についての検討

結論は、「理論的には劣化しないが、現実には劣化する」である。以下に理由を書く。

まず、本文に書いた状況での音質劣化は、音量を下げた時点で生ずるものが主である。音量を下げることによってデータの有効ビット数が減るため、振幅分解能が減る(例: ものすごく小さい音が消える)ためだ。音を格納するデータフォーマットが浮動小数点型であれば、おそらく分解能が減ることはないが、整数型の場合には減る。その程度は以下のように試算できる。

音量を-23dB下げた場合、1ビットは約6dBなので、23/6= 約3.8ビット減る。

これによるダイナミックレンジの減少量は、データフォーマットを16ビットとすれば、3.8*6= 22.8dBである(音量を下げた分(23dB)そのもの)。

(2020/1/2 12:28記) 注: その後、Spotifyが音量正規化値の計算に使っているReplayGainの基準音量は-14LUFS相当であることが分かった。そのため、実際に下がる音量は9dB程度で、減るビット数は1.5ビット程度と少なく、特にポップ音楽では、音質の劣化もダイナミックレンジの減少もほとんど問題にならない。

実害について考えれば、対象はポップ音楽であり、そのダイナミックレンジを高々18dB(約3ビット分)程度と推測すれば、音量を下げた残りのビット数は16-3.8= 12.2ビットで、音源の3ビットより充分大きいので、記録された振幅がよほど小さくない限り、問題ないと考えられる。

次に、増幅の影響を考える。増幅は乗算なので全く音質が劣化する要素はないが、現実には、処理系や出力のデータフォーマットは整数型で取り得る範囲が有限なため、大きく増幅すると上限を超えて(オーバーフローして)音質が劣化する。つまり、波形の超過分がカットされるので、音が変質する(例: 歪む)。

この検討中に気付いたのだが、私が"Speak to me"で感じた不自然な感じは、オーバーフローによるものだった。具体的には、音量正規化時に過大に増幅するとオーバーフローが生じ、その超過分をカットすると生じる(これはリミッターの動作であり、本文中の「コンプレッサー」は実際にはリミッターであった)。

不自然さが起こる原因を詳しく推測すると、この曲は低音(鼓動)が強いため、それがオーバーフローしてカットされるのだろう。カットされるのが単発的(不定期)や短時間(瞬間的)に起こるのなら気づきにくいからまだいいのだが、この曲の場合は、定期的に起こる鼓動で、テンポが遅いために比較的長時間音が大きい状態なので、カットされる期間が長く、その間の他の音の聞こえ方が変わって不自然になるのだろう。

この現象はSpotifyアプリの音量正規化だけでなく、私の環境でも起こったので気付いた。具体的には、次のような処理をした時に、Spotifyアプリの音量正規化(Normal)と同様の不自然さが生じた。

Spotifyアプリの音量正規化(Quiet) → アンプ(増幅率: 6-9dB程度) → リミッター

また、Spotifyアプリの音量正規化(Quiet)だけでは不自然さは生じなかったので、問題はリミッターに起因する可能性が高い。

なお、「リミッターが原因だったら使わなければいい」ということはない。リミッターがなくても、超過分はどこかで(例: DACで出力する時)カットされ、それはリミッターよりもひどい音質劣化を生じる可能性が高い。

(12/19 22:23) 補足: 上でデータフォーマットを16ビットと想定したのは、Spotifyアプリの出力がそう("s16le")だからで、通常のOSのサウンドシステムはもっとビット数の多いフォーマットをサポートする。例えば、私の使っているJACK Audioは32ビット浮動小数点である。だから、音質の観点ではSpotifyに音量正規化をさせるのは得策でない。上述の、音量を下げることによるダイナミックレンジの低下などが起こる。が、もし仮にJACKの中やその手前のPulseAudioで行うなら、劣化する可能性はほとんどない。

その後の増幅はJACKで行っているので、通常の増幅率ではオーバーフローしないから、音質劣化も発生しないはずだ。しかし、元々のデータが最大値に近いほうに詰められているためにオーバーフローするし、そうでなくてもDAC(サウンドカード)に出す時にオーバーフローする。それを防ぐには、リミッターを入れるか、音量を下げて(= 適当な値で除算して)全体的なレベルを小さくして(= 小さい方にずらす)DACに出すことが考えられる。

結局、後者はSpotifyの音量正規化(Quietモード)の小さい音のまま出力することと同等である。もちろんそれでも良かったのだが、他のプレーヤーと音量を合わせたいから増幅しようとした。

 

PS. SpotifyアプリからのRG値取得には、音楽圧縮フォーマット展開用ライブラリ(vorbisを使っているようだ)をすげ替えればできるかと思ったのだが、自前で作っているかスタティックリンクしているらしく、外部のものは使っていなかった。考えが甘かったが、まあ、そうれはそうだろう・・・ あとは、逆コンパイルしてバイナリエディットとかいう手もあるかも知れないが、「うーん」だ。それに、プログラムの改ざん検証をしているかも知れないから、できないかも知れない。

なんてことを考え出すから、寄り道が増える訳で・・・

  •   0
  •   0

使っているうちに不満(例: うるさい曲がある)が出て来たために、Spotifyの自作ミニプレーヤー(minisp)の音量正規化処理で、音量の補正量をやはり自作再生履歴DB(Mlhi)に記録しおいてそれがあれば使えるようにしようと思ったのだが、そもそも、元々の方式がいい加減では補正ばかりになって良くないことに気付いた。それで、まずは音量正規化処理を改良することになり、今は、その改良した方式の評価のために、Spotifyで再生している曲の音量を自動で測定する機能を作っている※。音量はできるだけ聴感に近い方がいいので、ラウドネス(Integrated loudness: "I", 参考)にした。随分目的から離れてしまった気がするが、きっと気のせいだろうw 自分でやり出したこととはいえ、なかなか面倒だが、いろいろな物を組み合わせて機能を実現するのはおもしろい。

※なぜ自動化しようと思ったのかというと、ラウドネスメーターはあらかじめ曲の先頭で計測開始しておかなければ、正確なIntegrated loudnessの値が出ないので、だらだらと評価がてら聴いていて「大き/小さ過ぎるかな?」(調整がおかしい?)と思ってからでは遅く、再計測しなくてはならないからである。再計測にしたって、曲全体を再度聴くのは苦痛なので、先頭だけなど一部になって、正確でなくなってしまう。曲間で自動リセットしてくれるような測定アプリがあればいいが、そういうものはなかった。また、GUIに表示された測定値を見て手で記録するのは面倒だし間違い易いから、自動でファイルに記録できれば好都合だ。

更に、複数の補正条件・設定の比較についても、それぞれの条件で評価用のプレイリストを再生しておけば(僕が聴いて居なくても、スピーカーで音を出さなくても)通して測定できるので、(この機能が完成した暁には)容易になるはずだ。

更に、普通に再生しながら、補正条件とその結果の音量を測定してDBに記録しておき、次回はそれに基づいて最適な音量に調整するってことも可能な気がしていて楽しい。

更に、今思い付いたが、AIみたいな機能で、長時間いろいろな曲を自動再生して勝手に学習させて、設定を自動調整するなんてのもいかにもおもしろそうだが、先は長いし、そもそもSpotifyを聴くだけなのにそこまでする必要があるのかと・・・w

こうやって風呂敷夢を広げるから、大変になるのだ。

詳しくは別に書くつもりだが、音量正規化の基本的な処理は、従来と同じようにSpotify APIで取得できる曲(トラック)の特徴量(loudnessとenergy)を組み合わせて、曲の本来の音量を推測(復元)し、それを元に正規化している。今回は、その推測の方法を改良しようとしている。今までは思い付きで対数あるいは指数関数を使っていたが、今は下のグラフのような、energyによって特性(係数)が変化する式を試している。グラフはいかにももっともらしくて うまく行きそうに思えるが、そんなことはないw それに、これは何かの理論に基づいている訳ではなく、やっぱり思い付きや試行錯誤からの経験によるものである。試すとまあまあうまく行く(しないよりはずっといい)のだが、やっぱり限界はあるし、値に問題はなくても聴覚に合わないことがある(合わないものが充分に少なくなったら、補正量をDBに入れようと思っている。が、いつになることやら・・・)。

あと、以前のように、公開DBに音量正規化用の値(再生ゲイン)などがないか探したたら、2つ見付かった。一つは前回も見付かったDynamic range databaseで、もう一個はAcousticBrainzだ。前者は、前回は(記憶している限りでは)APIがないのとレパートリーが狭そうなので止めた。後者は、言い方は悪いが「玉石混交」(「ゴ○屋敷」などもっとひどい言い方はあるが、それは言い過ぎだろう)で、全く手軽に使えないので却下した。確かにデータは多いのだが、全然整理されておらず、ただ数字があるだけで、同じIDなのにそれぞれ随分違っていてどれが正しいのか分からず、禄に検索もできなかったら、どうやって使うのかと思う。

作業の途中で分かったことも多かった。SpotifyのAPIから得られるloudnessは多くの場合はIntegrated loudnessまたはReplayGainと同様(同等)のものなのだろうが、そうでないことも多い。中で変・特殊な処理(音量(loudness)が小さいけどenrgyが大きい曲では更にloudnessを小さくしているフシがある)をしている可能性と、データが誤っている場合もありそうだ。そもそもSpotifyアプリで使っている再生ゲインを出してくれれば、こんな苦労をしなくて済むのだが(アプリの一時ファイルを見たりしたが、それらしい値は見つからなかった)・・・

そもそも、Spotifyアプリの音量正規化処理が「普通」だったら、こんな苦労は全くしなくていい(実際、したい訳じゃなくて、ただ音楽を聴きたいw)のだが、前回書いたように、やっぱり謎の処理をしていることが分かった(何人かの方が書かれていた: )。どうやら、アプリにコンプレッサーとかリミッターのような処理が入っていて、特にすごく音量が小さい曲(僕が気付いた曲: Pink Floyd: "The dark side of the moon"の"Speak to me")でおかしくなるようだ。再生ゲインの値がおかしい可能性はあるにしても、せめてその余計な機能がなければまだ良かったのに、どうもお節介な感じだ・・・

ラウドネスの測定プログラムは、GUIのものならいくつかあるのだが、測定・記録を自動化するのは困難なので、スクリプト(jack_captureで音を録り、ffmpegのebur128フィルタでラウドネスを計算する)を作ってミニプレーヤーに組み込んだ。基本的には、ただ再生しているだけでデータが貯まるから楽ちんなのだが、例によっていろいろ凝るから本末転倒になって、処理が複雑になればバグは増えるからデバッグが大変で、また勝手に疲れている。 ← イマココ

 

PS. 以前、「Spotifyには満足している」と書いたが、誤りではない。が、それはあくまでも曲目と音質についてであって、機能は別であるw

PS2. これを書いていて、技術バカにありがちな、「フラット(あるいはリニア)信仰(あるいは症候群、至上主義)」という言葉を思い付いた。やっぱり、こだわり過ぎは駄目なんだろうと思う。が、気軽に聴いている時に、曲のたびに「うるさい!!」とか「小さい・・・」とイライラしてボリュームを調整するのは嫌だってのは大いにある。

PS3. Evernoteやスマフォ・PCのおかげで紙やペンとは無縁の日々なのだが、さすがにグラフの形を考えるのはEvernoteでは無理で(タブレットなら手描きできそうだが、それも煩雑な気がする)、紙が必要だった。が、すぐに使えたのは小さい電話用のメモ帳しかなかったw

(12/14 13:11 少し修正)

  •   0
  •   0