-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update Bs1770gainBackend to handle bs1770gain v0.6.0 XML output #3480
Conversation
* Remove `0%\x08\x08` from output (backspace code doesn't resolve; progress percentages get spliced in) * Handle changed attributes/fields: * `sample-peak` attribute `factor` is called `amplitude` instead * Album summary is not included in a `summary` tag now, but in two separate `integrated` and `sample-peak` tags * Handle `lu` attribute * Get bs1770gain version * If v0.6.0 or later, add `--unit=ebu` flag to convert `db` attributes to LUFS * May be useful later on ### Output examples Track: ``` <!-- analyzing ... --> <bs1770gain norm="-18.00"> <track total="1" number="1" file="02 tïtle 0.mp3"> <integrated lufs="-70.00" lu="52.00"/> <sample-peak spfs="-72.28" amplitude="0.00"/> </track> <integrated lufs="-70.00" lu="52.00"/> <sample-peak spfs="-72.28" amplitude="0.00"/> </bs1770gain> <!-- done. --> ``` Album: ``` <!-- analyzing ... --> <bs1770gain norm="-18.00"> <track total="2" number="1" file="02 tïtle 0.mp3"> <integrated dbfs="-70.00" db="52.00"/> <sample-peak dbfs="-72.28" amplitude="0.00"/> </track> <track total="2" number="2" file="02 tïtle 1.mp3"> <integrated dbfs="-70.00" db="52.00"/> <sample-peak dbfs="-72.28" amplitude="0.00"/> </track> <integrated dbfs="-70.00" db="52.00"/> <sample-peak dbfs="-72.28" amplitude="0.00"/> </bs1770gain> <!-- done. --> ```
* Fix unspecified `gain_adjustment` when method defined in config * Fix difference between dB and LUFS values in case of mismatched `target_level`/`method`: ``` db_to_lufs( target_level <dB> ) - lufs_to_dB( -23 <LUFS> ) ``` * Ignore single assertion in case of bs1770gain (cherry picked from commit 2395bf2)
* With `bs1770gain` installed the `Bs1770gainBackend` tests fail, but this should be fixed by beetbox#3480.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool; thanks for attacking this! Here are a few ideas.
beetsplug/replaygain.py
Outdated
'([0-9]+.[0-9]+.[0-9]+), ', | ||
call([cmd, '--version']).stdout.decode('utf-8') | ||
).group(1) | ||
except AttributeError: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m a little confused—what is the potential AttributeError here? Is it the stdout attribute of the call result?
Maybe it would be nicer to just do a single call to check both whether the command exists and to get its version. Then we’d just need to handle OSError, I think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's the stdout attribute.
Ok, I suppose there's no real chance that some weird version bs1770gain
doesn't handle --version
.
beetsplug/replaygain.py
Outdated
if type(text) == bytes: | ||
text = text.decode('utf-8') | ||
while '\x08' in text: | ||
text = re.sub('[^\x08]\x08', '', text) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This replacement is somewhat surprising! Maybe a comment would be useful here to describe what’s going wrong?
beetsplug/replaygain.py
Outdated
parser.StartElementHandler = start_element_handler | ||
parser.EndElementHandler = end_element_handler | ||
|
||
try: | ||
if type(text) == bytes: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if type(text) == bytes: | |
if isinstance(text, bytes): |
beetsplug/replaygain.py
Outdated
parser.StartElementHandler = start_element_handler | ||
parser.EndElementHandler = end_element_handler | ||
|
||
try: | ||
if type(text) == bytes: | ||
text = text.decode('utf-8') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it necessary to do this conversion, or shall we perhaps just do the substitution directly on the bytes (with a bytes pattern)? That would avoid hard-coding an encoding, for example...
beetsplug/replaygain.py
Outdated
parser.StartElementHandler = start_element_handler | ||
parser.EndElementHandler = end_element_handler | ||
|
||
try: | ||
if type(text) == bytes: | ||
text = text.decode('utf-8') | ||
while '\x08' in text: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be safer to loop until the string stops changing. Otherwise, this runs the risk of this character being present but the pattern not matching (e.g., if it occurs at the beginning of the string).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To me it seems more readable to cover that case in the pattern by also replacing \x08 at the start of the string
b'[^\x08]\x08|^\x08'
then I can just explain it in a comment since I should write a bit about what's going on here anyway (:
* safer version comparison * regex bytes directly * handle b'\x08 ...' case * test_replaygain.py: injected command output should match the type of the actual output
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good! I have a couple of questions within, but I think this is basically ready to go. Would you mind adding a quick changelog entry?
beetsplug/replaygain.py
Outdated
except OSError: | ||
raise FatalReplayGainError( | ||
u'Is bs1770gain installed?' | ||
) | ||
except AttributeError: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the reorganization, but I'm still not 100% sure when this exception can be raised. Isn't it the case that the command_output
object will always have a stdout
member if the call was successful?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is an edge case in test_replaygain
where the backend is tested while bypassing calls to bs1770gain
.
It was patching None
to stdout there, I made it patch bs1770gain 0.0.0,
instead.
…arsing # Conflicts: # docs/changelog.rst
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks lovely; thank you for your persistence!
Fixes #3479.