[foobar2000] 重複曲を除く Playlist Tree 用 Scheme コード
foobar2000 Playlist Tree を使って「レーティングが 4 以上の曲」を取り出そうとして,以下の Query を今まで使っていました.
Source: @database Criteria: rating GREATER 3
しかしこの方法だと,違うアルバムに同じ曲が入ってるなどするときに,それらが両方ともツリーに入ってしまうので若干不便です.foobar2000 の "Remove Duplicates" はファイルのパスで同じかどうかを判定しているために使えませんでした.
そこで,Playlist Tree の Scheme によるカスタマイズに目を付け,「レーティングが 4 以上の曲で,かつ重複しているものは最初に検索で見つかった 1 曲だけにする」という Scheme コードを書きました.
; RATING が 4 以上の曲だけを得る.
; ただしアーティストとタイトルが重複する曲は列挙された最初の1曲だけにする
(begin
; 曲の一致性を判定する比較するための文字列を得る関数
(define getKey (lambda (handle)
(format-title handle "%title%%artist%")
))
; getKey 関数の結果に基づいて,handle1 と handle2 が同じかどうかを判定する述語
(define isEqualKey? (lambda (handle1 handle2)
(if (equal? (getKey handle1) (getKey handle2)) #t #f)
))
; isEqualKey? の結果に基づいて,指定したリストにhandleが入っていれ
; ば #t なければ #f を返す
(define isInList? (lambda (l handle1)
(let ((already-added #f))
(begin
(for-each (lambda (handle2)
(if (isEqualKey? handle1 handle2) (set! already-added #t))
) l)
already-added
)
)
))
(define addSongs (lambda (handle)
(add-node handle (list
(format-title handle "%artist%")
(format-title handle "%album%")
(format-title handle "%track%. %title%")
))
))
(define songs_candidate (list))
; リスト l に既に同じ曲(一致性の判定は isInList? が行う) があれば
; 追加しない
(define addToList (lambda (handle)
(if (isInList? songs_candidate handle)
()
(set! songs_candidate (cons handle songs_candidate))
)
))
; RATING > 3 の曲リストを作って,songs_candidate に入れる.
(for-each-db-entry (lambda (handle)
(addToList handle))
"rating GREATER 3"
)
; songs_candidate をツリーに追加する
(for-each addSongs songs_candidate)
)
Lisp 系言語のコードをまともに書くのは今回が初めてな上,手続き型言語の考えがどうしても頭から離れず,begin
使いまくりです (begin は C でいうカンマ演算子のようなもので,引数を順番に評価し,最後に評価した引数を値とする関数です).ちゃんと動くのでよしとします.
あとはこれらを以下のようにして Playlist Tree のクエリに登録します.これで作業完了です.
Source: @scheme Criteria: (空欄) Format: (上に書いたコードをここに貼り付ける)
これを導入したときのツリーは下のような感じになります.赤線で囲んだツリーが今回書いたクエリによるもので,上が最初に書いていたクエリによるものです.重複が取り除かれていることがわかります.
これで重複を気にする必要がなくなりました.
トラックバック
トラックバック URI: https://www.pakunet.jp/hoge/trackback/2007102101
トラックバックはありません.