feat: dynamic range compressor for dialogue boost / action limiting - #3117
feat: dynamic range compressor for dialogue boost / action limiting#3117fgmitesh wants to merge 57 commits into
Conversation
This class implements a real-time dynamic range compressor as an AudioProcessor, allowing for audio signal compression based on specified parameters. It includes methods for configuring audio format, processing input, and managing internal state.
Added support for dynamic range compression in audio sink.
Added a DynamicRangeCompressor instance to the audio sink for live parameter updates.
|
TESTING IS REMAINING = DRAFT FOR NOW |
|
It's almost done (Yeah it's W.I.P) |
Added constants for compressor settings in FullScreenPlayer.
Fix missing newline at the end of CS3IPlayer.kt
Added a new SwitchPreference for compressor settings.
Added new strings for compressor settings and updated existing ones.
Updated layout properties for compressor dialog and adjusted button configurations.
|
It's working now but needs little work |
|
done +tested+optional (player settings) defualt off |
Updated compressor settings restoration logic to always restore settings when opening the dialog and when the player UI loads.
Refactor compressor dialog functions for clarity and efficiency, updating variable names and UI interactions.
Updated compressor dialog layout to follow the speed_dialog.xml pattern, including adjustments to width, orientation, and component arrangement.
Updated default compressor settings for better audio control.
|
Fixed some minor bugs now it's fully ready I checked it on tv and phone it works perfectly now |
Removed LGPL attribution and simplified comment.
fire-light42
left a comment
There was a problem hiding this comment.
First review based on quick testing and reading. It is a very good and cool feature, but needs some small refinement.
| import kotlin.math.pow | ||
|
|
||
| /** | ||
| * Real-time dynamic range compressor ported from VLC's compressor. |
There was a problem hiding this comment.
Is this derivative of the compressor.c in VLC or is it just implementing the same algorithms used? This matters for licensing.
| @Volatile var enabled: Boolean = false | ||
| @Volatile var threshold: Float = -24f // dB, -30..0 | ||
| @Volatile var ratio: Float = 8f // n:1, 1..20 | ||
| @Volatile var attackMs: Float = 5f // ms, 1..400 |
There was a problem hiding this comment.
These are pretty much magic numbers. Please comment on what these do in a way to make it clear why these constants are chosen. Is it from a spec? What happens if we make the attackMs too low or too high, etc...
| On | Off →down→ slider row →down→ presets row →down→ stays (wraps) | ||
| Apply / Reset / Cancel reachable via nextFocusDown from slider row | ||
| --> | ||
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
There was a problem hiding this comment.
This dialog does not work on a phone at all.
The buttons do not fit.
| binding.compressorEnableBtt to compressor.enabled, | ||
| binding.compressorDisableBtt to !compressor.enabled, | ||
| ).forEach { (btn, active) -> | ||
| btn.setBackgroundColor( |
There was a problem hiding this comment.
This only updates the background, but the text remains white, leading to white on white.
| import kotlin.math.pow | ||
|
|
||
| /** | ||
| * Real-time dynamic range compressor ported from VLC's compressor. |
There was a problem hiding this comment.
This text is only understandable for someone with a lot of knowledge already. You can keep the complexity if you want, but you must add/change the text to make it understandable for people without domain knowledge. Even a simple sentence describing the goal of a dynamic range compressors would go a long way.
| ) | ||
|
|
||
| fun syncPresetButtons(active: com.google.android.material.button.MaterialButton?) { | ||
| val ctx = requireContext() |
There was a problem hiding this comment.
Never use requireContext(), it will crash even when it should not. Use the nullable context object to explicitly handle null state.
|
I'll tweak stuff according to reviews u done thanks |
Updated documentation and comments for clarity on dynamic range compressor parameters and functionality.
|
fixing minor error |
Updated string formatting for compressor_on_format to use positional arguments.
Adds a real-time dynamic range compressor accessible via a new
"Compressor" button next to Tracks in the player controls.
Ported from VLC's compressor.c (LGPL, Steve Harris / Ronald Wright).
Implemented as a Media3 AudioProcessor injected into DefaultAudioSink
— sits directly in the audio pipeline, zero overhead when disabled.
Controls: threshold, ratio, attack, release, makeup gain.
All adjustable live via sliders with no player reload needed.
Settings are persisted across sessions.
Defaults: threshold -14dB, ratio 4:1, attack 10ms, release 50ms,
makeup +6dB.
Works with both nextlib and default decoder paths.
Full TV remote navigation. Correctly included in isDialogOpen().
This PR was developed with AI assistance (Claude by Anthropic) for implementation and bug hunting. All code has been tested on a real Android TV device and a phone.