Script Help with Adding Bitrate to Folder

scripting
picard
Tags: #<Tag:0x00007f23c5b193c0> #<Tag:0x00007f23c5b19168>

#1

I’ve been trying to come up with a way to have Picard add the bitrate to the folder that contains the album. On VBR, this is challenging because on 15 different tracks, you’ll have 15 different bitrates. What I’m trying to do instead, is first check for a constant bitrate and set a new variable with that number, and then check to see if the bitrate falls within a range. I think the issue may be the nested ifs, or bitrate may simply not be responding to functions as I would expect.

    $if2(%albumartistsort%,%artistsort%)/
    $if($ne(%albumartistsort%,),
    %artist% - 
    %date% - 
    %album% {%label% %catalognumber%}  
    [
    $upper(%_extension%) 
    $if($eq(%_bitrate%,320.0),$set(_folderbr,320))
    $if($eq(%_bitrate%,256.0),$set(_folderbr,256))
    $if($eq(%_bitrate%,192.0),$set(_folderbr,192))
    $if($eq(%_bitrate%,160.0),$set(_folderbr,160))
    $if($eq(%_bitrate%,128.0),$set(_folderbr,128))
    $if(
        $gt(%_bitrate%,220.000),$if(
            $lt(%_bitrate%,310.000),$if(
                $gt(%_folderbr%,0),$set(_folderbr,V0)
    )))
    $if(
        $gt(%_bitrate%,170.000),$if(
            $lt(%_bitrate%,210.000),$if(
                $gt(%_folderbr%,0),$set(_folderbr,V2)
    )))
    %_folderbr%
    ]/)$if($gt(%totaldiscs%,1),%discnumber%,)$if($ne(%albumartist%,),$num(%tracknumber%,2). ,)$if(%_multiartist%,%artist% - ,)%title%

In reality all it does is use the last instance that %_folderbr% checked. So right now it would rename everything as V2, and if I moved the V0 code block below it, it would rename everything to V0.

Any thoughts?


#2

Cleaned this up some and simplified for debugging. Relevant snippet:

[
$upper(%_extension%)
$if($eq(%_bitrate%,320.0),$set(_folderbr,320),
$if($eq(%_bitrate%,256.0),$set(_folderbr,256),
$if($eq(%_bitrate%,192.0),$set(_folderbr,192),
$if($eq(%_bitrate%,160.0),$set(_folderbr,160),
$if($eq(%_bitrate%,128.0),$set(_folderbr,128))))))

$if($gt(%_folderbr%,0),$noop(),
$if($gt(%_bitrate%,220),$set(_folderbr,V0),
$if($lt(%_bitrate%,219),$set(_folderbr,V2),
$set(_folderbr,Err)
)))
$if($eq($upper(%_extension%),MP3), %_folderbr%)
]

Any CBR album works fine, any VBR album gets renamed to [MP3 Err]. So I believe what’s going on is %_bitrate% is a string, and $eq works because the strings match, but $gt, for instance, will not because it’s doing a math comparison on a string type.


#3

The problem here is that $if does not work here as you probably expect. $if itself is a function call, and it gets called with the result of $set. It is not a control structure of the language. So $result gets executed even before $if gets called.

The solution is quite simple, use $if inside the $set:

$set(_folderbr,$if($eq(%_bitrate%,160.0),160,))

Please excuse the short answer and lack of code formatting, answering from my mobile.


#4

I actually just figured it out. For whatever reason, %_bitrate% will not work with $gt(), probably because it’s declared as a float and float comparisons are always funky. But, if you cast it as an int, by way of taking the first 3 characters, $gt() works again.

[
$set(_numbr,$left(%_bitrate%,3))
$upper(%_extension%)
$if($eq(%_bitrate%,320.0),$set(_folderbr,320),
$if($eq(%_bitrate%,256.0),$set(_folderbr,256),
$if($eq(%_bitrate%,192.0),$set(_folderbr,192),
$if($eq(%_bitrate%,160.0),$set(_folderbr,160),
$if($eq(%_bitrate%,128.0),$set(_folderbr,128))))))

$if($gt(%_folderbr%,0),$noop(),
$if($gt(%_numbr%,220),$set(_folderbr,V0),
$if($lt(%_numbr%,219),$set(_folderbr,V2),
$set(_folderbr,Err)
)))
$if($eq($upper(%_extension%),MP3), %_folderbr%)
]

This will obviously break on stuff <100 kbps. Not applicable to me, and easily fixed with some $replace().


#5

I was just compelled to point out the logical fallacy here:
$gt(%_numbr%,220) checks for anything greater than 220, so 220 is not included.
$lt(%_numbr%,219) checks for anything less than 219, so 219 is not included.

This means than anything where %_numbr% equates to 219–220 (both numbers included) will not get matched by this. You probably want something more like:

$if($gte(%_numbr%,220),$set(_folderbr,V0),
$if($lt(%_numbr%,220),$set(_folderbr,V2),

This will $set(_folderbr,V0) for anything where %_numbr% is 220 or greather than and $set(_folderbr,V2) when it’s less. Thus, all (numeric) values are included in the comparison and you won’t suddenly end up with weird edge cases. :wink:

You should be able to just use $if(%_folderbr%,,…). Unless there’s more to your script than what you’ve shown, %_folderbr% will not contain a value at if it didn’t get set in the previous block, so numeric comparison makes less sense (IMHO) than just checking whether it exists at all. (Also, $noop() literally does nothing, so it should be possible to remove it—but on the other hand, keeping it might be nice for readability.)

You can use $set(_numbr,$div(%_bitrate%,1000)) (ie., divide the bitrate by 1000) to circumvent this instead of removing the 3 right most characters. :slight_smile:


#6

Thanks for the clarification. Some of the code was left overly simple just to work through the immediate issue, and I’ll be working on cleaning it up. However, one of your suggestions does not work.

$if($gte(%_numbr%,220),$set(_folderbr,V0),
$if($lt(%_numbr%,220),$set(_folderbr,V2),

Fine.

$if(%_folderbr%,,

Fine as well, thank you. Couldn’t figure out the expected syntax for just checking whether a variable was empty.

$set(_numbr,$div(%_bitrate%,1000))

This won’t work in the current build. Here’s the complete script, if you’d like to review that.

$if2(%albumartistsort%,%artistsort%)/
$if($ne(%albumartistsort%,),
%artist% - 
%date% - 
%album% {%label% %catalognumber%}  
[
$noop($set(_numbr,$left(%_bitrate%,3)))
$set(_numbr,$div(%_bitrate%,1000))
$upper(%_extension%)
$if($eq(%_bitrate%,320.0),$set(_folderbr,320),
$if($eq(%_bitrate%,256.0),$set(_folderbr,256),
$if($eq(%_bitrate%,192.0),$set(_folderbr,192),
$if($eq(%_bitrate%,160.0),$set(_folderbr,160),
$if($eq(%_bitrate%,128.0),$set(_folderbr,128))))))

$if(%_folderbr%,,
$if($gte(%_numbr%,220),$set(_folderbr,V0),
$if($lt(%_numbr%,220),$set(_folderbr,V2),
$set(_folderbr,Err)
)))
$if($eq($upper(%_extension%),MP3), %_folderbr%)
]/)$if($gt(%totaldiscs%,1),%discnumber%,)$if($ne(%albumartist%,),$num(%tracknumber%,2). ,)$if(%_multiartist%,%artist% - ,)%title%

If you try it as is, a VBR MP3 will get tagged as [MP3 Err]. If you noop the line with $div and un-noop the line with $left it’ll work.