らんだむ

PCとTVをオーディオケーブルで繋ぎ,アニメの主題歌や挿入歌をキャプチャし,歌詞を手打ちし,アーカイブするのが趣味?のはず?です.始めたのは恐らく23年前,高専に入学し,初めてのPCを買い,周りの連中の影響でアニヲタイズした頃です.現時点では約7600曲が溜まっています.

一覧をExcelファイルで管理しています.このExcelのマクロで,以下3種類のデータを更新・生成しています.

  • 歌詞HTML(ヘッダの曲名等を更新)やMP3へリンクするHTML(番組名等含む表形式)
  • コレクションしているリストのHTML(ホームページ掲載用)
  • PC操作中にBGMとしてランダム再生するプレイリスト

■プレイリスト生成ロジック改良

今回,プレイリスト生成のロジックを改良しようと思い立ちました.現在は,プレイリストに追加するかどうかを示すフラグの列を設け,そこが「O」になっているMP3ファイルのパスのみをプレイリストへ出力するようにしています.このフラグは,ホームページへ掲載するリストHTMLを更新するタイミングで,1年以上前の曲を「X」に変える運用にしています.これにより,直近1年の曲のみが再生されることになります.

アニソン管理ファイル
アニソン管理ファイル

しかし,たまにはもっと昔の曲と再会し,懐かしくなりたいなと.そこで,以下の要領でピックアップした曲をプレイリストへ出力したいと思います.

  • 直近6箇月は全て登録する.
  • それ以前は古いほど少なく,新しいほど多くなるような割合でランダムに採用する.
  • 全部で1000曲をプレイリストへ出力する.

■収録日の一覧化

そのためにはまず,収録日を一覧化する必要があります.大量なので,いちいち調べて手入力するのは非現実です.それだけで心折れちゃう.いろいろ思案した結果,MP3ファイルの最終更新日をピックアップすれば良いのではと.こんな単純なことに,なかなか思い至れませんでした.灯台下暗し.

マクロでの実装は簡単.最終更新日というか,ファイルの新しさが知りたいので,最古のデータを0とした月数を算出するようにしましょう.

Const AGE_ORIGIN As Integer = 2002 * 12 + 3
Dim fso As New FileSystemObject
Dim f   As File
Dim age As Integer
Set f = fso.GetFile("xxx.mp3")
age = Year(f.DateLastModified) * 12 + Month(f.DateLastModified) - AGE_ORIGIN

VBAがあまりに久しぶりすぎて,参照するライブラリ名「Microsoft Scripting Runtime」を思い出せませんでした.最古のデータは2002年3月で団子状になっていました.MP3なるものが出回り始めたこの頃,Wave(PCM)から一気にまとめて変換したんでした.これだとそれ以前の収録日情報が不正確になりますが,そこまでの精度は不要でしょう.

■加重ランダム採用

難しいのは,新しさに応じた重みでランダム抽出する方法です.VBAのRndメソッドが返す0以上1未満の乱数は,一様分布に従うものだと思います.これをどう活用するか.三つの方法を考えました.以下の5曲が候補に残っていて,そこから3曲を選ぶ例で説明したいと思います.

  • 曲A:月数1
  • 曲B:月数1
  • 曲C:月数2
  • 曲D:月数2
  • 曲E:月数4

■加重ランダム採用方法#1

最初に考えたのは,乱数を一つ算出し,それに対応する積算月数の曲を採用する,というのを繰り返す方法です.

月数積算月数採用条件採用率
A11Rnd*10<110%
B12 = 1+11≦Rnd*10<210%
C24 = 1+1+22≦Rnd*10<420%
D26 = 1+1+2+24≦Rnd*10<620%
E410 = 1+1+2+2+46≦Rnd*10<1040%

Rndメソッドの戻りが0.5だった場合,曲Cが採用されます.そして次の1曲は,以下の方法で採用されます.という風に繰り返す方法.

月数積算月数採用条件採用率
A11Rnd*8<112.5%
B12 = 1+11≦Rnd*8<212.5%
D24 = 1+1+22≦Rnd*8<425%
E48 = 1+1+2+44≦Rnd*8<850%

この方法の問題は,処理時間がかかることです.1曲選ぶたびに積算月数を再計算する必要があります.計算量は候補数×採用数のオーダーです.実行に1分以上かかりました.これは嫌.

■加重ランダム採用方法#2

次に考えたのは,月数に基づく確率で各曲の採用是非を調べていく方法です.

月数採用条件採用率
A1Rnd<0.1 = 1/(1+1+2+2+4)10%
B1Rnd<0.1 = 1/(1+1+2+2+4)10%
C2Rnd<0.2 = 2/(1+1+2+2+4)20%
D2Rnd<0.2 = 2/(1+1+2+2+4)20%
E4Rnd<0.4 = 4/(1+1+2+2+4)40%
  1. 乱数を算出し,0.1未満だったら曲Aを採用する.
  2. (曲Aを採用したかどうかに関わらず)乱数を算出し,0.1未満だったら曲Bを採用する.
  3. (曲AやBを採用したかどうかに関わらず)乱数を算出し,0.2未満だったら曲Bを採用する.
  4. 以下同様

この方法だと,一巡では採用数に達しないことが多いです.実際は分母がもっともっと大きいので,なかなかこの採用条件が満たされないのです.そのため,方法1ほどではないにせよ,何度か回す必要があります.例えば,1巡目で曲BとDが採用された場合は,2巡目で下表のチェックをしていくことになります.

月数採用条件採用率
A1Rnd<0.1 = 1/(1+2+4)14%
C2Rnd<0.2 = 2/(1+2+4)29%
E4Rnd<0.4 = 4/(1+2+4)57%

やっぱり処理時間,かかりました.全部で600巡くらい必要で,十数秒かかりました.これもちょっと嫌.

■加重ランダム採用方法#3

最後に考えたのは,方法2をベースに,残採用数が多いほど採用条件を緩める方法です.

  1. 曲Aの採用条件を「Rnd<0.3 = 1/(1+1+2+2+4)*残採用数3」とする.
  2. 乱数が0.3未満だった場合
    1. 曲Aを採用する.
    2. 曲Bの採用条件を「Rnd<0.2 = 1/(1+1+2+2+4)*残採用数2」とする.
  3. 乱数が0.3以上だった場合
    1. 曲Aを採用しない.
    2. 曲Bの採用条件を「Rnd<0.3 = 1/(1+1+2+2+4)*残採用数3」とする.

この方法でも,一巡では採用数に達しませんでした.何度か回す必要があります.とはいえ,加速項のお陰で,5巡くらいで済みました.処理時間は数秒程度.いいね.

こうして方法3でプレイリストに採用された曲の月数統計をグラフ化しました.良い感じです.頭痛に見合う価値があります.

月数に対する採用率
月数に対する採用率

みたいなことを眠い中やっつけるのが会社での私の仕事の一つです.上記の数理統計学的な理論立てが合っていたとしても,プログラムへの落とし込みに間違いがあると台無し.眠い中,どっちに誤りがあるのか探したりするの辛い.どっちもが合っていたとしても,目標とする結果に達していなければ,別の案を捻りだす必要があります.フレーフレー私.

今日観たアニメ(4101)

  • [C]ダーウィンズゲーム「圧砕エイス」(第7話 2/21深夜)

    痛い痛い.どうしてそう痛めつけるの好きかな.花屋さんに鈴音たんや嘘発見器氏も続くのかと思っちゃいました.スイソーダ,女子が水を出して男子が凍らせてましたが,人格換えないとできない芸当なのかしら.

  • [C]ランウェイで笑って「存在感オーラ」(第7話 2/21深夜)

    才能あるからと推され,望まぬ仕事で周囲から敵意を向けられる,辛い.そりゃオーラも黒々としますわ.顔を見せない脇役でも頑張ろう,とモチベーションを努めて高めていたのに,バランス悪くなるということでそれすら敵わない低身長,涙,泣いてないし.

  • [B]ヒーリングっど♥プリキュア「カワイイ!なりたい!キュアスパークル誕生」(第4話 2/23朝)

    うっかり口利いてしまう猫と,慌てん坊の黄色,名コンビですね.キラやば,めちょっく,キラっと閃いたりする直近のキュアピンクの暴走属性は今回,黄色が引き継ぎましたか.で,静と動でぎくしゃくする次回,あるある.

  • [D]ONE PIECE「緊急事態ビッグ・マム大接近!」(第922話 2/23朝)

    触れたものを熟れさせる悪魔の実の能力の発動に際して,印を結んで忍術風に演出している厨二病.屋根から忍び込むナミ,座敷から抜け出すロビン,井戸から魂出すブルック,そもそも何を探しているんだったっけ.

  • [C]キラッとプリ☆チャン「ついに開幕!ジュエルコレクション!だよん!」(第97話 2/23朝)

    だいあを司会に推す観客の呟きを受け,即行出ていって働くだいあ凄い.逆に,ジュエルコレクションの運営側は誰を司会に掲げるつもりだったのかと.喧嘩して揉み合うえもあんなはいつものことですが,ツインテが絡まって解けなくなるのはなるほど,そう来たかと.うっかり握手して赤面するとか,ういやつ.

  • [C]BORUTO「鬼灯城を脱出せよ」(第145話 2/23夜)

    部屋に鳥の餌を撒いて,何のつもりかと思ったら,掃除の場を設けて作戦会議をするためでしたか.代理城主,忍術使えたんですね.ま,忍者向けの監獄だから当然か.毛玉氏,最終的に味方してくれる感じしかしない.

  • [C]ぼくのとなりに暗黒破壊神がいます。「Blurry Eyes」(第7話 2/23深夜)

    Mの般若の双子の妹の登場.この占い師はどんな個性をお持ちか.とか思っていたら,糸目エスパーが開眼.オッドアイで催眠術.敵に回せない.後遺症なのか,妹氏,エスパーにご執心の様子.小雪と花鳥は相変わらず,仲良しで.

  • [C]アイドリッシュセブン「5人と2人」(第12話 2/23深夜)

    解るけど,急いでいるって言ってるんだから道を空けてあげなって.妹を知っているという嘘,言語道断.こりゃファンを嫌いになるのも仕方ない.「それって良いニュース?」はどうかと思いましたが,「馬鹿だから言ってくれないと解らない」の素直な感じいいね.発音は片言なのに,丁寧な言い回しは完璧じゃないの.

  • [C]翠星のガルガンティア「離別」(第8話 2/23深夜)

    船団長,葬送.若くして後継者に指名され,想像できない重圧.でも,仲間に恵まれていますね.救難信号ですら到達が数万年後というレド,引き揚げ屋と一緒にい船団を離れるか.といってもすぐ戻ってくるんでしょ.なんてったってこっちには金元いるぜ.

  • [A]映像研には手を出すな!「大芝浜祭!」(第8話 2/23深夜)

    そんな攻めた部活あるんか!っつー面白さてんこ盛り.金森Pの根回し,言うだけのことはありますね.読モ水崎氏で充分に釣ったり,ペットボトルロケット部に宣伝を手伝ってもらったり,生徒会からの追撃をダンボールロボット部の協力で逃れたり,空調部を強請って体育館を冷やして客寄せしたり.からの上映,生アテレコ,滾る内容でした.さらに役者水崎父母との和解っつーかなんつーかいいね.