Thanks for the great player. Long time user, first-time poster...

By default, I like to have all my music on shuffle, except for a few tags (broken tracks, redundancies, Christmas music, etc.).

I set up a playlist called "Everyday", defined as:

All of: Label broken isn't set; Label redundant isn't set; Label skip isn't set, etc.

When I do that, all my tracks are in the playlist, even the ones with those labels set.

When I switched to Any of: to my surprise, it worked — a couple of weeks ago. Today, I was surprised with some spoken word and Christmas music. Any of: seems to have changed, but All of: is still the same.

Am I doing something wrong? Is this a gmusicbrowser bug? Advice greatly appreciated.

tl;dr: How can I build a playlist based on negative filtering of labels?

Quote from: crism on March 20, 2011, 20:00:01
By default, I like to have all my music on shuffle, except for a few tags (broken tracks, redundancies, Christmas music, etc.).

If you want just shuffle, you could build 'weighted random' option where you can select labels you don't want to be played (set weight = 1, and check [ x ] inverse for all of them)

Quote from: crism on March 20, 2011, 20:00:01
How can I build a playlist based on negative filtering of labels?

I have no problems with
"All of:
* label A isn't set
* label B isn't set
...
"
It results as a playlist containing only songs with no labels. Are you sure your 'playlist filter' is set to use this filter instead of 'all songs'? Can you see those unwanted songs in your filtered playlist (to check this, for example insert column "labels", sort by clicking it and check first and last song of list)?

Thanks for the reply, laite. More info follows:

Quote from: laite on March 21, 2011, 12:01:40
If you want just shuffle, you could build 'weighted random' option where you can select labels you don't want to be played (set weight = 1, and check [ x ] inverse for all of them)

A good suggestion. I'll try that, though I'd still like the ability to easily save these different label-based playlists.

Quote from: laite on March 21, 2011, 12:01:40
Quote from: crism on March 20, 2011, 20:00:01
How can I build a playlist based on negative filtering of labels?

I have no problems with
"All of:
* label A isn't set
* label B isn't set
...
"
It results as a playlist containing only songs with no labels. Are you sure your 'playlist filter' is set to use this filter instead of 'all songs'? Can you see those unwanted songs in your filtered playlist (to check this, for example insert column "labels", sort by clicking it and check first and last song of list)?

Good diagnostic suggestion—when I display labels, and use the playlist as a filter, the undesired labels definitely show up.

I suspect that the "label X isn't set" filter works differently than I think. Lemme get Boolean for a minute...

I think of "label X isn't set" as not(X(t)) where t is a track, and X(t) returns true if the label is set; !X for a shorter notation.

I would expect All of: to be a logical and, and Any of: to be a logical or.

With All of: Label X isn't set, Label Y isn't set, I would expect and(not(X(t)),not(Y(t))), or: !X and !Y. Now, !X and !Y is equivalent to !(X or Y), exactly what I want.

But what I get with All of: is only the undesired labels, i.e., X or Y. It seems like All of: with the negative label assertion is broken.

With Any of: Label X isn't set, Label Y isn't set, I would expect or(not(X(t)),not(Y(t))), or: !X or !Y. This is equivalent to !(X and Y).

That should show all the tracks, unless they have all the undesired labels set. Indeed, this works; when I add all the bad labels to one track, it falls off the playlist. However, a couple of weeks ago (and maybe there was an update in between), I was getting the desired behavior, !(X or Y).

It really feels to me like there is some mis-applied De Morgan going on inside the system. (-:

Oh, information I should have included in the post which was the very top of this thread: this is gmusicbrowser 1.0.2, installed from the package manager for Ubuntu 10.04 Lucid Lynx.

Thanks.

First I doubt there was any update of gmusicbrowser in your system recently as sadly v1.0.2 is very old, though it is the last officially "stable" version (v1.1.7 should be present in the next ubuntu).

I tried with both the latest and with v1.0.2 and it all seems to work, so I would guess it is probably some confusion with what filter is currently applied.
When running gmusicbrowser with the -debug option, you can see the actual code that is used for the filter, I get :

- with v1.0.2:
  - all of :
    sub{ [ grep {($::Songs[$_][23]!~m/(?:^|\x00)Bootleg(?:$|\x00)/ && $::Songs[$_][23]!~m/(?:^|\x00)Broken(?:$|\x00)/)} @{$_[0]} ]; }
  - any of :
    sub{ [ grep {($::Songs[$_][23]!~m/(?:^|\x00)Bootleg(?:$|\x00)/ || $::Songs[$_][23]!~m/(?:^|\x00)Broken(?:$|\x00)/)} @{$_[0]} ]; }
- with 1.1.7:
  - all of :
    sub{ [ grep {(! do {my $v=$Songs::Songs_label__[$_]; $v ? ref $v ? grep(1==$_, @$v) : ($v == 1) : 0} && ! do {my $v=$Songs::Songs_label__[$_]; $v ? ref $v ? grep(2==$_, @$v) : ($v == 2) : 0})} @{$_[0]} ]; }
  - any of :
    sub{ [ grep {(! do {my $v=$Songs::Songs_label__[$_]; $v ? ref $v ? grep(1==$_, @$v) : ($v == 1) : 0} || ! do {my $v=$Songs::Songs_label__[$_]; $v ? ref $v ? grep(2==$_, @$v) : ($v == 2) : 0})} @{$_[0]} ]; }

in both cases the simplified version is :
- all of : (! containsX && ! containsY )
- any of : (! containsX || ! containsY )

Quote from: Quentin Sculo on March 21, 2011, 18:14:07
First I doubt there was any update of gmusicbrowser in your system recently as sadly v1.0.2 is very old, though it is the last officially "stable" version (v1.1.7 should be present in the next ubuntu).

I'll keep my fingers crossed for the update.

Quote from: Quentin Sculo on March 21, 2011, 18:14:07
I tried with both the latest and with v1.0.2 and it all seems to work, so I would guess it is probably some confusion with what filter is currently applied.
When running gmusicbrowser with the -debug option, you can see the actual code that is used for the filter, I get :

I hadn't thought of trying that, thanks. I think I can prove I'm not crazy. (-:

I had Any of: set, and when I ran with -debug:


$sub=eval sub{ [ grep {($::Songs[$_][23]!~m/(?:^|\x00)broken(?:$|\x00)/ || $::Songs[$_][23]!~m/(?:^|\x00)redundant(?:$|\x00)/ || $::Songs[$_][23]!~m/(?:^|\x00)skip(?:$|\x00)/ || $::Songs[$_][23]!~m/(?:^|\x00)spoken\ word(?:$|\x00)/ || $::Songs[$_][23]!~m/(?:^|\x00)yule\ only(?:$|\x00)/)} @{$_[0]} ]; }


which is fine. Changing the playlist back to All of: and running with debug, I see something much different; the full output is included up to that point here:


watch AAPicture HASH(0xa1d7678)
GStreamer::Interfaces perl module not found -> visuals not available
Reading saved tags in /home/crism/.config/gmusicbrowser/tags ...
Reading saved tags in /home/crism/.config/gmusicbrowser/tags ... done
Use of uninitialized value in join or string at /usr/bin/gmusicbrowser line 2173.
Use of uninitialized value $_[9] in join or string at /usr/bin/gmusicbrowser line 2173.
Select : filter Filter=HASH(0xaa1cbe0) sort r1l10 song keep play  staticlist
makesub filter=(&-23fbroken-23fredundant-23fskip-23fspoken word-23fyule only)
filter=(&-23fbroken-23fredundant-23fskip-23fspoken word-23fyule only)
$sub=eval sub{ [ grep {do { my $r;exists($hashes[0]{$_}) and $r=1 and last for split /\x00/,$Songs[$_][23];-$r;}} @{$_[0]} ]; }
ChangeWatcher 0 ARRAY(0x927bf90) ARRAY(0xa6e2990) CODE(0x9d29f78) CODE(0x9d2a408) CODE(0x9d1ef48) Filter=HASH(0xaa1cbe0) CODE(0x9d2a108)
filter fields : '23'
pos : 126


That is a very different filter, obviously. I can confirm that the "everyday" filter is currently applied, and that it is defined as All of: a bunch of label-not-sets. The only thing I did between those two runs was to edit the playlist, change Any of; to All of:; save it; re-apply it, then quit and restart.

Looks like I should try to upgrade on my own and see if it persists.

Right, I forgot about the optimization used when many values are used : rather that checking each song for each value, a hash is made to quickly check if the value is in the list.

there was indeed a small bug in v1.0.2, which resulted in -$r at the end of the code, rather than !$r :)
I fixed it in git v1.0.x branch, though there won't be any more release of that branch :
http://git.gmusicbrowser.org/commit/743b7436c0

The bug is not present in v1.1.x.

Quote from: Quentin Sculo on March 21, 2011, 23:06:38
Right, I forgot about the optimization used when many values are used : rather that checking each song for each value, a hash is made to quickly check if the value is in the list.

there was indeed a small bug in v1.0.2, which resulted in -$r at the end of the code, rather than !$r :)
I fixed it in git v1.0.x branch, though there won't be any more release of that branch :
http://git.gmusicbrowser.org/commit/743b7436c0

The bug is not present in v1.1.x.

Thanks for all your time, Quentin. I'll live with it for now, and petition the Ubuntu gods to update their distro while I upgrade independently.