Flick 0.16.0-beta.1
0.16.0-beta.1 is the audio engine release. Native DSD playback, a 31-band parametric equalizer, full metadata editing, song sharing, star ratings, a flagship home widget redesign, USB volume control, and a reworked audio backend selection system all land in this beta. The Rust engine can now deliver raw DSD bitstreams to your DAC, modify tags in-place, and export share cards for your music.
Overview
This beta adds eleven headline features:
- DSD playback engine — native DSD, DoP (DSD over PCM), Auto mode, and PCM decimation for DSF, DFF, and WavPack DSD files
- Metadata editor — read and write audio tags (title, artist, album, year, genre, track number) via a Rust backend, with SAF file writing on Android
- Parametric equalizer 31-band — expanded from 10 to 31 bands at 1/3-octave ISO frequencies, with horizontal band editors and a detail panel
- Song sharing cards — four share card templates (album art, lyrics, minimal, solid color) with export and save-to-gallery
- Star rating system — 1–5 star ratings on songs with animated overlay, persistent storage, and custom player action button placement
- Flagship home widget v2 — new card and split layouts, tabbed widget settings, multi-widget support
- USB volume control — dedicated volume popup with slider and mute for isochronous USB audio engines
- Album and folder sorting — sort albums and folders by title, artist, duration, track count with persistent preferences
- Audio engine selector — manual engine selection from the menu screen, toggleable from UI settings
- Lyrics enhancements — length tag injection, filename matching preferences, save location dialog, preview filtering
- UAC2/DAC backend refactor — scoring-based output strategy selection, DAP detection via signature registry, device compatibility guides
Highlights
- DSD playback: The Rust DSD engine supports three output modes — Native (raw bits via JNI
AudioTrackwithENCODING_DSD), DoP (packed into 24/32-bit PCM frames with 0x05/0xFA markers, up to DSD512), and PCM decimation (CIC+FIR conversion to integer-multiple PCM rates). Auto mode probes device capabilities at runtime and picks the best available path. WavPack DSD files (.wv) are automatically detected via mode flags and routed to the DSD engine. WavPack PCM files route through Symphonia. - Metadata editor: Full tag editing built into the player screen. Reads/writes ID3, Vorbis comments, and other tag formats through a Rust metadata editor module (
lofty-powered). Changes are written to the file via Android's SAF (for content URIs) or direct filesystem access. Scanner preserves local edits on rescan and skips background metadata for edited songs. New year and genre fields in the song model with sort support. - 31-band EQ: Parametric equalizer expanded from 10 to 31 bands using 1/3-octave ISO center frequencies (20 Hz–20 kHz). UI redesigned with horizontal band editors and a detail panel for precise adjustments. Import/export still supported in JSON and TXT formats.
- Share cards: Share a song as an album art card, lyric card, minimal text card, or solid color card. Templates render the song info, album art, and share app. Cards can be saved to the device gallery as images. Accessible from the song actions bottom sheet.
- Star ratings: Tap stars on any song card or in the full player. Animated star overlay with half-star precision. Ratings stored persistently per song and accessible as a sort option. The rating button is one of several customizable player action buttons.
- Flagship widget: New larger widget layouts — a full card widget with album art, playback controls, and progress bar; a split layout with art on one side and controls on the other. Widget settings screen restructured with tabbed interface separating mini player and flagship widget options. Multi-widget support with per-widget theme preferences.
- USB volume popup: When using the isochronous USB audio engine, a dedicated volume popup provides precise slider control and mute. Accessible from a player action button and the audio settings screen.
- Engine selector: Choose your audio engine manually from a card on the main menu screen. The selector is toggleable from Settings > Interface. Helpful when auto-selection picks a suboptimal path for your setup.
- Lyrics polish: Synced LRC output now includes a
[length:]tag with total duration. Save location dialog lets you choose where to export LRC files. New lyrics filename matching preference syncs sidecar filenames to the audio filename. Online lyrics search now shows previews and supports filtering. - Backend refactor: The audio backend selection system was rewritten to use a scoring-based approach — each backend (USB Direct, DAP Native, Mixer, etc.) returns a compatibility score, and the highest scorer wins. DAP detection moved from a brand enum to a signature registry for easier extensibility. Device compatibility guides and extensibility docs added for DAC/DAP developers.
What's New
DSD Playback Engine
- Native DSD: JNI
AudioTrackbackend opens AndroidAudioTrackwithENCODING_DSD(encoding 29). A dedicated render loop feeds raw DSD bytes from the engine's ring buffer directly to the DAC — no PCM conversion, no decimation. Supports DSD64–DSD512. - DoP transport: DSD bits packed into 24-bit or 32-bit PCM frames with 0x05/0xFA marker bytes. DSD64 → 176.4k 24-bit, DSD128 → 352.8k 24-bit, DSD256 → 705.6k 24-bit, DSD512 → 705.6k 32-bit. Dual-probe fallback at init: tries original DSD rate then 2× rate. Supports USB Direct and Mixer strategies.
- Auto output mode: Runtime probing chain: Native DSD (DAP brand/model check +
ENCODING_DSDprobe) → DoP → PCM decimation. Picks the highest-fidelity working path. Effective mode is displayed in debug state JSON. - Format decoders: DSF (Sony container,
dsf-meta), DFF (Philips container,dff-meta), WavPack DSD (.wvwith DSD content, vendoredwavpack-sysFFI crate). WavPack PCM support via dedicated decoder thread with resampling and channel remixing. - Decimation pipeline: CIC+FIR decimator converts DSD to integer-multiple PCM rates (44.1k–705.6k). CIC filter state split into integer and fractional parts for precision. FIR tuned to 256 taps with Kaiser beta 8.0. Sinc filter formula corrected with frequency response test.
SequentialBlocksdeinterleaving for channel layout support. - DSF fixes: Seek calculation corrected for metadata chunks. Sample counting fixed for multi-block streams. Sample data offset read from FMT chunk metadata (not hardcoded).
- Experimental gating: Native, DoP, and Auto modes gated behind an experimental flag. Only PCM decimation is ungated by default. DSD rate label and quality badge displayed in the full player screen.
Metadata Editor
- Rust metadata editor module reading and writing tags via
lofty(ID3, Vorbis comments, APE tags) - Dart
MetadataEditorServicebridging the Rust FFI - Metadata editor screen: edit title, artist, album, album artist, year, genre, track number, comment
- SAF file writing via
writeFileBytesViaSafmethod channel for content URI files - Direct filesystem writes for regular files
hasLocalEditsfield onSongEntitytracks locally modified metadata- Scanner skips background metadata extraction for locally edited songs
- Scanner preserves local edits when matching scanned songs to existing database entries
- Year and genre fields added to
Songmodel with sort options
Parametric Equalizer 31-Band
- Expanded from 10 to 31 bands at 1/3-octave ISO center frequencies (20, 25, 31.5, 40, 50, 63, 80, 100, 125, 160, 200, 250, 315, 400, 500, 630, 800, 1000, 1250, 1600, 2000, 2500, 3150, 4000, 5000, 6300, 8000, 10000, 12500, 16000, 20000 Hz)
- UI redesigned with horizontal band editors showing frequency, gain, and Q per band
- Detail panel for precise gain/Q entry on the selected band
Song Sharing Cards
- Album Art Share Card: full-bleed album artwork with song title and artist overlay
- Lyric Share Card: current lyrics rendered as styled text
- Minimal Share Card: clean text-only layout
- Solid Color Share Card: single-color background with song info
- Share bottom sheet: select template → share via system share sheet or save to gallery
share_plusintegration for cross-app sharing
Star Rating System
RatingButtonwidget: 1–5 stars with animated overlay and half-star precisionRatingServicepersists ratings per songRatingProviderfor reactive state management- Player action buttons are now customizable — left and right button slots configurable in preferences
PlayerActionButtonmodel with enum of available actions (rating, share, lyrics, visualizer, shuffle, loop, etc.)
Flagship Home Widget v2
FlagshipWidgetProvider(Kotlin): newAppWidgetProviderwith theme support- Card layout: full-bleed album art, progress bar, play/pause/skip controls
- Split layout: album art on one side, controls and info on the other
- Widget settings screen restructured with tabbed interface:
- Mini player tab: existing customization (background, accent, content toggles)
- Flagship tab: new theme and layout preferences
- Multi-widget implementation plan for future widget variants
- Flick logo drawable added for widget branding
USB Volume Control
IsoVolumePopupwidget: slider + mute toggle for isochronous USB audio engines- Accessible as a player action button
- UAC2 volume control section added to audio preference screen
- Only active when the isochronous USB engine is running
Album and Folder Sorting
- Album sort sheet: sort by title, artist, duration, track count with ascending/descending toggle
- Folder sort sheet: sort by name, song count, duration
- Sort preferences persist across sessions
- Songs within albums sorted by album before display
- Folder entries sorted before display in song list
Audio Engine Selector
- Engine selector card on the main menu screen showing available audio engines
- Toggle visibility from Settings > Interface > UI Customization
showEngineSelectorpreference with persistence- Useful for manual override when auto-selection picks a suboptimal path
Lyrics Enhancements
[length:MM:SS.XX]tag injected into synced LRC output with formatted total duration- Save location dialog: choose export directory when saving LRC files
- Lyrics filename matching preference: sidecar filenames can sync to the audio filename
- Lyrics settings screen: configure filename matching and other lyrics preferences
- Online lyrics search now shows preview snippets for each result
- Search results support filtering (synced, plain-text, instrumental)
- Lyrics panel UI polished with accent-colored chips and improved empty state
UAC2 / DAC Backend Refactor
- Audio backend selection rewritten to use scoring-based candidates instead of hardcoded fallbacks
- Each backend (
UsbDirect,DapNative,MixerBitPerfect, etc.) returns a compatibility score - DAP device detection moved from brand enum to signature registry — new brands/models can be added without modifying core logic
AudioBackendtrait withdescriptor()method for backend metadata- USB DAC compatibility notice widget added to UAC2 settings
- Device compatibility guide expanded with MOONDROP Dawn Pro
- DAC/DAP extensibility guide documentation for developers
List Pagination and UI Performance
- Songs and folder screens now use paginated lists with cached artwork
SongsStaterefactored to compute sorted songs and folder groups in the factory constructor (one-time computation)- Folder navigation uses
MaterialPageRouteinstead of customPageRouteBuilder
Library Scanner
- Per-folder deep scan override: individual folders can bypass the fast scan and use full filesystem scanning
useDeepScanpreference controls the default behaviorFolderEntityextended withuseDeepScanfield, preserved on upsert- Audio file extension filter removed — scanner now considers all files in configured directories
Other Improvements
- Nav bar overflow: Animated overlay menu for nav items that don't fit. Labels wrapped with
FittedBoxto prevent overflow. Warning shown when >4 buttons are enabled. - Programmatic nav: Disabled essential pages can still be navigated to programmatically (e.g., from widget intents or deep links).
- Album art grid: Album art candidates screen redesigned with grid layout for faster browsing. Aspect ratio adjusted for better thumbnails.
- Notification colors: Album artwork colors extracted for the music notification background. Color parameter added to notification service.
- Bit-perfect safety: Bit-perfect mode default volume set to -40 dB safety level to prevent ear-splitting output when switching to a high-gain USB path.
- Crossfade fix: Engine correctly marks as stopped when crossfade completes with no next source (prevents stuck state).
- Track update:
updateTrackmethod added to Rust audio engine for in-place track metadata updates. - Backend path fix: Rust backend path mismatch handled correctly after skipping a track.
- Song card refactor: Swipe overlay conditionally rendered to reduce widget tree overhead.
- Lyrics scroll: Scroll animations chained sequentially for smoother transitions.
- Bottom sheet: Height constrained to 50% of screen for better one-handed use.
- Dynamic padding: Header styling updated with dynamic padding fix.
- Compatibility notice: Bit-perfect toggle disabled when isochronous USB engine is not active.
Post-Release Additions & Fixes (May 2026)
The following was merged after the initial 0.16.0-beta.1 cutoff:
Milestone Tracking (User Achievements)
- MilestoneService: Tracks total songs played and accumulated listen time across sessions. Five tiers: 100 songs, 500 songs, 1,000 songs, 10 hours, 50 hours — each with its own encouraging message and Ko-fi call-to-action.
- Milestone dialog: Displayed from the app shell when a new milestone is achieved. Each milestone is shown only once.
- Player tracking:
_trackMilestones()adds listen duration per song and checks for milestones;pendingMilestoneNotifiertriggers the dialog. - Preferences:
welcomeCardDismissedkey stores whether the welcome card has been permanently dismissed.
Support Flick (In-App Donation Screen)
- SupportFlickScreen: Full-screen page with three animated info tiles explaining that Flick is a solo project, where donations go (Play Store fees, audio testing gear, DSD development), and a pulsing-border Ko-fi button.
- Settings header heart button: Pulsing heart icon in the settings header navigates to the support screen. Uses a repeating ease-in-out animation.
- Recap screen credit: Ko-fi support button and credit line added to the listening recap screen footer.
Animated Welcome Card
- Menu screen welcome card: Gradient-bordered card introducing the app, displayed at the top of the menu screen beneath the greeting. Slide+fade entry animation, dismiss with reverse animation.
- Persistent dismissal: Dismissing the welcome card sets
welcomeCardDismissedto true, preventing it from reappearing on subsequent launches.
Audio Engine Fixes
- Audio session activation: Rust engine now calls
AudioSession.instance.setActive(true)on Android to properly request audio focus — prevents ducking and allows playback to coexist with notifications. - Volume slider gain mapping: Exponential curve replaced with a gentler 0-20 dB linear mapping. Slider position now maps linearly to dB, providing more precise control in the usable range.
- Skip WAV conversion for normal engine: Content URI staging and WAV conversion are now skipped when the standard (non-USB) Android engine is active, reducing unnecessary file I/O.
UI Performance Fixes
- Orbit scroll refactor:
OrbitScrollnow usesValueNotifierinstead ofsetStateper item, and cache size is limited to prevent unbounded growth during long scrolling sessions. - Card width caching: Card width computed once per layout and reused;
RepaintBoundarywrapper removed to reduce compositing layer overhead. - Full player screen: Removed the
SingleChildScrollViewwrapping the column layout, eliminating layout jank on devices where the content exceeds the viewport.
Known Issues
- DSD volume control: PCM decimation produces silence when DoP is not available, blocking the volume control fallback path. Hardware volume is used as primary control; digital volume is not available for native DSD streams. See
docs/DSD_VOLUME_CONTROL_STATUS.mdfor details. - Experimental DSD modes: Native, DoP, and Auto modes are gated behind an experimental flag. These paths are functional but not yet enabled by default. PCM decimation remains the default DSD output mode.
- WavPack PCM decoding: WavPack PCM files route through a dedicated WavPack decoder thread (not Symphonia). Resampling and channel remixing are supported but some edge cases with hybrid/lossy WavPack may differ from the standard decoder path.
- Metadata editor: Writing tags to content URI files (SAF) requires Android to grant write access. Some file managers may not propagate write permissions to the staging cache.
Files Changed
| Area | Key Paths |
|---|---|
| DSD Engine | rust/src/audio/dsd_engine/, rust/src/audio/decoder_handle.rs, rust/src/audio/strategy.rs
|
| WavPack | rust/vendor/wavpack-sys/, rust/src/audio/wavpack_decoder.rs
|
| DSD Formats | rust/src/audio/dsd_engine/format/dsf.rs, dff.rs, wavpack.rs
|
| DoP Pipeline | rust/src/audio/dsd_engine/dop.rs, pipeline.rs, pcm_output.rs, output_router.rs
|
| Native JNI | rust/src/audio/dsd_engine/native/, android/.../audio/DsdAudioTrackManager.java
|
| Engine Core | rust/src/audio/engine.rs, rust/src/audio/backend.rs, rust/src/audio/resampler.rs
|
| Metadata Editor | rust/src/metadata_editor/, lib/services/metadata_editor_service.dart, lib/features/player/screens/metadata_editor_screen.dart
|
| EQ | rust/src/audio/equalizer.rs, lib/features/settings/equalizer_screen.dart
|
| Sharing | lib/widgets/share_cards/, lib/features/player/widgets/share_bottom_sheet.dart
|
| Rating | lib/widgets/rating_button.dart, lib/providers/rating_provider.dart, lib/services/rating_service.dart
|
| Widget v2 | android/.../widget/FlagshipWidgetProvider.kt, lib/features/settings/screens/widget_settings_screen.dart
|
| USB Volume | lib/widgets/iso_volume_popup.dart, lib/features/settings/screens/uac2_preferences_screen.dart
|
| Sorting | lib/features/albums/screens/album_sort_sheet.dart, lib/features/folders/screens/folder_sort_sheet.dart
|
| Engine Selector | lib/features/home/widgets/menu_screen.dart, lib/providers/app_preferences_provider.dart
|
| Lyrics | lib/services/lyrics_service.dart, lib/services/online_lyrics_service.dart, lib/features/settings/screens/lyrics_settings_screen.dart
|
| UAC2/DAC | rust/src/uac2/backend.rs, rust/src/audio/dap_profile.rs, rust/src/audio/output_strategy.rs
|
| Scanner | lib/services/library_scanner_service.dart, rust/src/api/scanner.rs
|
| Nav Bar | lib/widgets/flick_nav_bar.dart
|
| Player UI | lib/features/player/screens/full_player_screen.dart, lib/features/player/widgets/player_action_buttons.dart
|
| Docs | docs/DSD_ARCHITECTURE.md, docs/DSD_VOLUME_CONTROL_STATUS.md, docs/DAC_EXTENSIBILITY.md
|
Upgrading
- This release adds the
ENCODING_DSDAudioTrack path — no user action required beyond updating - Experimental DSD modes are disabled by default; enable from Settings > Audio > DSD Output Mode
- WavPack DSD files (
.wv) are automatically detected and routed — no configuration needed - Native DSD requires a device that reports
ENCODING_DSDsupport (most DACs from Android 12+) - The 31-band EQ replaces the previous 10-band EQ — existing presets are compatible; new bands default to 0 dB gain
- Metadata edits are written directly to files — back up your music if you plan to bulk edit
- The flagship widget is a separate widget from the mini player — add it from your launcher's widget picker
- Engine selector is hidden by default — enable from Settings > Interface > UI Customization