Archive for the 'Article' Category

Playlist Tree: Query Eye for the OCD Guy
April 24th, 2007

This article will build up an absurdly complex playlist tree query from a simple example.


  • foo_cwb_hooks
  • playlist tree panel
  • foo_playcount (official)
  • well tagged library

Step 1 – Music from the 60′s

Make sure you have a playlist tree panel in your layout. Then create a new query from the main menu by selecting “Libary->Playlist Tree->Root->New Query…” and fill in the fields with the following information:

Label: <Your choice>

Source: @database

Criteria: date GREATER 1959 AND date LESS 1971

*** Note, it is IMPORTANT that GREATER and LESS and AND be ALL CAPS

Format: $replace(%path%,\,|)

Maximum: 0

Population Sort Order: <blank>

Sort by Display Name: Checked

Automatically Refresh: Unchecked

Now, click Ok, and the query result should show up based on where they are located on your computer.

Step 2 – … And Rating > 2

Middle click, or right click while holding shift, on the query you created in Step 1, and change the criteria.

New Criteria:

date GREATER 1959 AND date LESS 1971
AND rating GREATER 2

Step 3 – … And Songs 4-6 Minutes in Length

New Criteria:

date GREATER 1959 AND date LESS 1971
AND rating GREATER 2
AND %length_seconds% LESS 360 AND %length_seconds% GREATER 240

Step 4 – … And Not Heard in the Last Week

New Criteria:

date GREATER 1959 AND date LESS 1971
AND rating GREATER 2
AND %length_seconds% LESS 360 AND %length_seconds% GREATER 240
AND (“$cwb_datediff(%last_played%,%cwb_systemdate%)” GREATER 7 OR NOT %last_played% HAS 20)

Step 5 – … And By Bob Dylan

New Criteria:

date GREATER 1959 AND date LESS 1971
AND rating GREATER 2
AND %length_seconds% LESS 360 AND %length_seconds% GREATER 240
AND (“$cwb_datediff(%last_played%,%cwb_systemdate%)” GREATER 7 OR NOT %last_played% HAS 20)
AND artist HAS bob dylan

Step 6 – … In Scheme

To use the built in scheme language, you must change the source to @scheme.

Then, you can enter the scheme code into the format field. For doing your own scheme queries, I suggest using an editor that knows how to edit scheme code such as Emacs, then copying and pasting the code into Playlist Tree’s format box.

The following code will give you basically the same query as step 5, but in scheme.

Source: @scheme

New Format:

(let ((filter
;; Notice that this filter string is basically the same as we used in the traditional query
;; We can use any traditional query strings here to select which songs we want
“date GREATER 1959 AND date LESS 1971″
” AND %length_seconds% LESS 360 AND %length_seconds% GREATER 240″
” AND rating GREATER 3″
” AND (\”$cwb_datediff(%last_played%,%cwb_systemdate%)\” GREATER 7 OR NOT %last_played% HAS 20)”
” AND artist HAS bob dylan”)))
(lambda (handle)
(let ((artist (format-title handle “%artist%”))
(album (format-title handle “%album%”))
(title (format-title handle “%title%”)))
(add-node handle (list artist album title))))
(when start-index
(play-from-playlist start-index)))

Step 7 – … Added to Album Playlists and Start Playing

New Format:

(let ((filter
;; Notice that this filter string is basically the same as we used in the traditional query
“date GREATER 1959 AND date LESS 1971″
” AND %length_seconds% LESS 360 AND %length_seconds% GREATER 240″
” AND rating GREATER 3″
” AND (\”$cwb_datediff(%last_played%,%cwb_systemdate%)\” GREATER 7 OR NOT %last_played% HAS 20)”
” AND artist HAS bob dylan”))
(start-index #f))
(lambda (handle)
(let* ((playlist-name (format-title handle “** %album%”))
(index (find-or-create-playlist playlist-name)))
;;; store the index of the first playlist we make
(when (not start-index)
(set! start-index index))
(add-to-playlist handle index)))
(when start-index
(play-from-playlist start-index)))

Step 8 – … And Hooked Up To a Button

If you look in the main menu under Libary->Playlist Tree->Refresh you should see options for refreshing all of your scheme queries. To hook up a scheme query to a Columns UI button, make sure you have a button toolbar somewhere in your layout.


  • Right click on the buttons and select “Customize…”.
  • Add a new button by clicking the Add button
  • Select the “Change…” button to select the action.
  • Select “Main Menu Items” from the command group
  • Select “None” for the item group
  • Find in your the command list “Libary/Playlist Tree/Refresh/<Your Query>”
  • Click Ok.
  • Change the Display to “Text”
  • Check “Use Custom Text”
  • Enter some text in there that will refer to the query.

When you are done, a new button should have shown up in your button layout with the label you provided. You can now click on that button to refresh the query which will run the scheme code and begin playing some good old school Bob Dylan that you haven’t listened in a while.

Playlist Tree and the Art of the Query
April 19th, 2007


Digg This

Playlist Tree began as a playlist manager that builds playlists as trees. Most audio players use a list based approach to playlists, but I wanted to be able to create hierarchies in my playlists, so that I could have greater control of how I listened to music.

Playlist Tree has become one of the most powerful playlist managers that I have used. That power comes at a price of a fairly steep learning curve to use it to its full potential.

PT acts a Columns UI Panel, and this article will assume that you already known how to make the PT Panel appear in your layout. If you don’t know how to operate Columns UI, please ask someone other than me ;-) . This article also assumes some familiarity with foobar2000 titleformatting.


Playlist Tree fofrplaylisttree


PT has 3 types of nodes in its trees. First, it supports nodes that represent a single playable item. These items can be dropped onto the playlist tree panel from a playlist view or from the Windows Explorer. Second, it has what I refer to as static folders, which can contain playable items or other static folders, or the third type of nodes, the query. Queries are what give PT its power.

All of these nodes can be moved around by dragging and dropping them in the panel, and items can be copied rather than moved if you hold down shift when you begin dragging.

When you drop folders from windows explorer, it will create folders for each directory, and subdirectory, and playable nodes for audio files.


Queries are PT’s automatic playlists. They let you enter the criteria for which tracks should show up in the results, and how you want the results to be laid out in the tree. They also let you place limits on the size of resultant list in the form of number of tracks, duration, filesize and number of subfolders.


(More here)

Source instructs PT which files to use as possible candidates for the playlist. In most situations @database is probably the desired source. But other sources exist such as @drop<> for using playlists and directories as a source, @node<> for using other tree nodes as source and @playlists and @playlist


Criteria lets you prune files from your source. If you want all the files in the source to show up in the resultant tree, then leave the criteria blank. Otherwise, you can use the same syntax as foo_playlist_gen to remove non-matching tracks. For example, if you wanted only tracks by the Beatles that you have rated 4 or higher, you can use “artist HAS beatles AND rating GREATER 3″ for your criteria.


Format specifies how the resultant playlist will be arranged. It use the foobar2000 titleformatting syntax. Tree layers are split using the | character. If you wanted all the files to be put into folders based on their artist, then the album and finally the title, the format string would look like “%artist%|%album%|%title%”.

Population Sort Order

Population sort order determines the order in which songs go through the playlist generation process. Its especially useful when you are using the maximum options. For example, if you wanted a list of 10 random songs, you would set the Population Sort Order to “$rand()” and the maximum to 10 tracks.

Playlist Generation Process

Under the hood, the tree in a query basically gets generated like this:

  • 1 – make a list of all possible songs based on source
  • 2 – sort the list based on population sort order.
  • 3 – prune off items that don’t match criteria
  • 4 – for each item, add it to the tree based on format.
  • 5 – stop if you reach the end of the list or hit the maximum whatever.
  • 6 – if Sort by display name is check, sort by display name.

Random Things You Should Know

If you hold shift while dragging and dropping nodes, you can make a copy rather than move.

By default, right clicking on a node will give the normal foobar2000 context menu options, holding down shift while right clicking or middle clicking on a node will give you the playlist tree specific context menu. (These are configurable)

PT is very configurable. To get to the preferences select File->Preferences from main menu, then look under Media Library->Playlist Tree Panel.

You can configure what happens when you select, double click, and middle click on nodes.

PT adds its main menu options under Library->Playlist Tree.

In addition to the main Playlist Tree panel, PT also adds a Playlist Tree Search panel you can use in your Columns UI layout to quickly search your trees.

You probably also want my foo_cwb_hooks plugin.

I like getting email from people who enjoy using my programs. I also keep track of bugs and feature requests. If you have questions on how to do something, please use the forums. Other people may benefit from the information or respond that way. My email is

The playlist tree discussion on the foobar2000 forums is here

I maintain my own forums here

I make and distribute PT because I enjoy using it myself, and I think others also enjoy it. But I also have a job, a fiancee, a mortgage payment, and a life. I wish I could implement every cool feature people suggest and respond to everyone’s post, but I have a limited amount of time that I can spend on this, so please forgive me if you don’t hear back from me on a bug or a feature request or a question.


As of version 3.0.0, PT contains an embedded version of the Scheme programming language. This is intended for advanced users.

The embedded scheme has the following benefits:

  • 1 – It is a real programming language with things like conditionals and loops.
  • 2 – Because it is a real programming language, you can do things that are flat out impossible with a normal playlist tree query.
  • 3 – Because it is a real programming language, I can add ways to script foobar2000 actions.
  • 4 – It’s easier to use than foobar2000 titleformatting for complex tasks (when you get the hang of it).
  • 5 – It’s hardcore.

See the MORE section for more information and links to examples.


More information about playlist tree can be found on the components homepage here.

More information about the embedded version of scheme in playlist tree can be found at here. I also suggest finding on online scheme tutorial or the book “The Little Schemer”.

Example queries can be found at here.