feat: dynamic range compressor for dialogue boost / action limiting - #3117
feat: dynamic range compressor for dialogue boost / action limiting#3117fgmitesh wants to merge 44 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 |
|
I tested it on mobile it works |
Updated layout to improve responsiveness and structure.
Updated default parameters for the dynamic range compressor to improve dialogue clarity and reduce crackling. Adjusted envelope handling and gain computation for better audio processing.
Refactor compressor dialog functionality to improve usability and maintainability. Adjust default values and streamline button actions.
Updated layout structure for compressor dialog to improve organization and navigation. Adjusted components for better alignment and functionality.
Refactor compressor dialog functionality, including snapshot handling and preset application.
Fix formatting issue by adding a newline at the end of the file.
|
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 |
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.