Archive for the 'Tips' 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.

Requirements:

  • 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
(string-append
;; 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”)))
(for-each-db-entry
(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))))
filter)
(when start-index
(play-from-playlist start-index)))

Step 7 – … Added to Album Playlists and Start Playing

New Format:

(let ((filter
(string-append
;; 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))
(for-each-db-entry
(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)))
filter)
(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.

Then:

  • 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.

How to make a Progress Bar
February 21st, 2007

The standard seek bar is all well and good but it doesn’t integrate well with Track Display and SCPL. A new approach is to use PanelsUI, the $drawrect function and a few of foobar’s standard functions. $drawrect was introduced in the original track info mod panel by Terrestrial and it uses a format like so:

$drawrect(X,Y,W,H,brushColor-R-G-B penColor-R-G-B OPTIONS)
$drawrect(10,10,50,5,brushcolor-200-200-200 pencolor-null)

X and Y determine the position of the bar, W and H determine the width and height, the brush colour is the fill colour of the box, pen colour is the border. Options can include alpha, border width and blurriness. From this basis a rectangle can be built that has a size dependent on a changing value, for instance a track’s progress.

When a track is playing, its progress can be called up using the string %playback_time_seconds%, similarly its total length is given by %length_seconds%. To convert this value into one that is usable the percentage of the track played must be converted into a relative width. For instance if our progress bar is to be 50 pixels across, at 50% played the rectangle drawn must be 25 pixels. This can be done using the following:

$muldiv(%playback_time_seconds%,50,%length_seconds%)

$muldiv first multiplies %playback_time_seconds% by 50 (width of rectangle) then divides that value by %length_seconds%. So, to check, if the track is 60 seconds long and is 30 seconds (half way) through: 30×50 = 1500, 1500/60 = 25 pixels. Using $puts we can quietly store this value in a variable, let’s call it “progress“:

$puts(progress,$muldiv(%playback_time_seconds%,50,%length_seconds%))

If this code is placed in a //PerSecond section of PanelsUI then it will change its value as often as we need it to. To draw this rectangle we use the $get function to include the variable:

$drawrect(10,10,$get(progress),7,brushcolor-200-200-200 pencolor-null)

Thus the complete code is as follows, the first rectangle is a border and an $ifgreater clause has been added so that no rectangle is drawn if no time has passed:

// PROGRESS BAR
$drawrect(9,9,52,7,brushcolor-null pencolor-101-101-101)
$puts(progress,$muldiv(%playback_time_seconds%,$sub($get(imgw),20),%length_seconds%))
$ifgreater($get(progress),0,
$drawrect(10,10,$get(progress),5,brushcolor-200-200-200 pencolor-null)
,)

PanelsUI Tabs
February 20th, 2007

PanelsUI has a number of fascinating uses. To get the ball rolling, the first Fooblog2000 tip shall explain how to make tabs in this component. An understanding of the trackinfo mod (now renamed Track Display) syntax and functions is helpful. This tip makes use of Three functions; $select which runs different code based on the stored value of a particular PVAR (or persisting variable); $panel which is new to PanelsUI and shows a panel, toolbar, visualisation or playlist in the desired configuration; and thirdly, $button2 which creates a button using text.

$select($add($getpvar(display.mode),1),
run this code when display.mode = 0
,
run this code when display.mode = 1
,
run this code when display.mode = 2
)

display.mode is the persisting variable, a value of 1 is added to its value to give correct $select operation. To change this PVAR a button such as the one below can be used:

$button2(0,160,0,0,140,14,'$font(Calibri,9,,155-155-155)Mode 1','$font(Calibri,9,underline,155-155-155)Mode 1,'PVAR:SET:display.mode:1',)'

This code creates a text button of size 140×14 pixels, 160 pixels down the page. The text is size 9, Calibri font and colour 155-155-155. When moused over the text becomes underlined. Clicking this button changes the value of display.mode from 0 to 1. Thus selecting and running a different set of code. If this code changes the panel that is shown then a tab system has been created – for example, showing a track display panel:

$panel(Option1,Track Display,0,20,%_width%,140,)

With name “Option1″ and panel determined by the second term “Track Display”, this code will show a panel the width of the screen of height 140, starting 20 pixels down the screen. Changing the second term to “Album list” for example will instead show the traditional album list panel.

A complete code would look a little like this:

$select($add($getpvar(display.mode),1),
$panel(Option1,Track Display,0,20,%_width%,140,)
,
$panel(Option2,Album list,0,20,%_width%,140,)
,
$panel(Option3,Console,0,20,%_width%,140,)
)
$button2(0,160,0,0,140,14,$font(Calibri,9,,155-155-155)Mode0,$font(Calibri,9,underline,155-155-155)Mode0,'PVAR:SET:display.mode:0',)
$button2(14,160,0,0,140,14,$font(Calibri,9,,155-155-155)Mode1,$font(Calibri,9,underline,155-155-155)Mode1,'PVAR:SET:display.mode:1',)
$button2(28,160,0,0,140,14,$font(Calibri,9,,155-155-155)Mode2,$font(Calibri,9,underline,155-155-155)Mode2,'PVAR:SET:display.mode:2',)

Download Panel Tabs.pui Example