Definitely happy to walk you through!
$if($eq(%album%,[non-album tracks]),$unset(album)$unset(albumsort))
This does remove the album from the tags, but only if it uses Picard’s default for non-album tracks – I’ve changed how it displays on my install, which is why I used “standalone” before, but you’ll obviously want it to match your own version. If you’d rather leave that on the file, I’ll include a line doing so further down. Personally, I’m perfectly happy having the “album” field be blank for recordings without any associated release. You may also want to add $unset
calls for discnumber
, totaldiscs
, tracknumber
, and totaltracks
if you’re being more aggressive in removing albums.
Basically, this is a standard conditional test; if the equality between the variable and the constant string returns true, run the two $unset
calls after the comma to clear the variables. As a note, surrounding a variable name in percent signs (like in the $eq
) means to get the value stored in it, while using it without (in the $unset
s) will either – depending on context – refer to the variable itself or just be a plain string. I’m not sure how much this comes up in Batch, but it’s probably better to think of variable names as keys into a string-string table rather than as special objects.
$set(_savealbum,$if($or($not(%albumsort%%album%),$and($or($not(%totaldiscs%),$lte(%totaldiscs%,1)),$or($not(%totaltracks%),$lte(%totaltracks%,1)))),
,
$if2(%albumsort%,%album%)/
))
$set
is unsurprisingly the opposite of $unset
; in this case, it’s basically saying "store the result of the $if
under the name _savealbum
. This brings up the second important thing about variables: if they’re prefixed with an underscore, you can use them as much as you want in Picard but they won’t be saved to the file. If we used the name savealbum
without a leading underscore, the file name wouldn’t change at all, but there’d be an extra text field with our chosen album folder hidden in the file. That won’t affect anything in terms of playability, but it’s unnecessary cruft and will show up if you ever have reason to look at the metadata.
Breaking that down further:
$if($or($not(%albumsort%%album%),$and($or($not(%totaldiscs%),$lte(%totaldiscs%,1)),$or($not(%totaltracks%),$lte(%totaltracks%,1)))),
this is just a really detailed condition to check if a file should be treated as a standalone recording. If you wanted to leave [non-album tracks]
in the tags, then you’d delete the first line unsetting the album variables and add its $eq(%album%,[non-album tracks])
in here:
$if($or($eq(%album%,[non-album tracks]),$not(%albumsort%%album%),$and($or($not(%totaldiscs%),$lte(%totaldiscs%,1)),$or($not(%totaltracks%),$lte(%totaltracks%,1)))),
otherwise, it checks whether either $not(%albumsort%%album%)
or that long combination of totaldiscs
and totaltracks
is true, which covers both the case of there not being any album tags and the album being a single track long.
$not(%albumsort%%album%)
This illustrates a handy trick for testing variables: $if
and similar consider an empty value to be false and anything else to be true; the above is a compact way of saying "neither %albumsort%
nor %album%
contain anything. Be careful while using it, though, as I’ve seen some people on here run into issues with it counting whitespace (from putting the condition on a new line) as true even when the variable is empty – and I think the behaviour might even be different between the naming and the tagging scripts.
$or($not(%totaldiscs%),$lte(%totaldiscs%,1))
This might be able to be simplified to $lte(%totaldiscs%,1)
, but I’m not sure what the behaviour is if %totaldiscs%
is empty, and the extra check isn’t going to hurt. Basically, this on its own doesn’t say anything and neither does %totaltracks%
on its own (there might be a single-track bonus disc), but combining the two in an $and
allows us to be sure that the entire release is just a single track.
Now that I’ve looked at the tags a bit more, if you only use MB releases, you’ll probably want to use %_totalalbumtracks%
rather than the more complex condition, but I can see that easily going wrong for any albums that aren’t being hooked up. An $if2(%_totalalbumtracks%,%totaltracks%,1)
might be best.
$if(%condition%,
,
$if2(%albumsort%,%album%)/
)
This is the full form of $if
complete with the “else” clause. As normal, if the condition is true, the first option is chosen (here setting _savealbum
to be empty) while if it’s false, it uses the first of $albumsort%
and %album%
to contain something ($if2
chooses the first non-empty value in the list) and adds another level of folders over those having no album – note that the path separator is included in the value of _savealbum
.
$and($lte($matchedtracks(),3),$not($is_complete))
$gt($sub($if2(%_totalalbumtracks%,%totaltracks%,1),$matchedtracks()),3)
$not($is_complete())
Finally, the last thing you’ll want to add for your particular situation is a means to get rid of album fields for partial albums; any of the above will work in different manners. The first line will match albums that you only have three or less tracks for, as long as at least one track is missing, the second will match those where you’re missing at least three tracks – both of which can be tweaked by changing the 3
– and the final is a shortcut for if you want to match any album with any missing track. Choose the one that sounds the best to you, and add it to the test with the $unset
calls.
Putting it all together, your script will probably look something like this:
$noop(I'd rather not save Picard's default album name to the tags)
$noop(Also, strip the album if it's missing tracks)
$if($or($not($is_complete()),$eq(%album%,[non-album tracks])),
$unset(album)
$unset(albumsort)
$unset(discnumber)
$unset(totaldiscs)
$unset(tracknumber)
$unset(totaltracks)
)
$noop(If neither album name is set, or if the album consists of a single track, put it in the artist's root)
$set(_savealbum,$if($or($not(%albumsort%%album%),$lte($if2(%_totalalbumtracks%,%totaltracks%,1),1)),
,
$if2(%albumsort%,%album%)/
))