hoge diary - October 21, 2007

[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: (上に書いたコードをここに貼り付ける)

これを導入したときのツリーは下のような感じになります.赤線で囲んだツリーが今回書いたクエリによるもので,上が最初に書いていたクエリによるものです.重複が取り除かれていることがわかります.

Scheme による 重複除去処理を施した Playlist Tree の図

これで重複を気にする必要がなくなりました.

コメント

名前(何でも可):

テキスト(http:// を含む内容は投稿できません):

トラックバック

トラックバック URI: https://www.pakunet.jp/hoge/trackback/2007102101

トラックバックはありません.


Valid XHTML 1.1! Valid CSS!
© 2004-2009 ぱくちゃん.
Last modified: Thu Nov 01 01:17:13 JST 2007