austinried cf272c4edc playback: apply the gain only from the item flush
Review follow-ups for the apply slice.

- Drop the media item transition application. It never supplied a gain
  the flush had not already supplied, and as a second writer it raced the
  playback thread: it applied the incoming item's gain while the outgoing
  item's buffers were still queued, scaling the previous track's tail by
  the next track's gain (reproduced at +12 dB). The flush is the only
  writer now.

  This reverses the earlier decision to keep it as a fallback. That was
  made on the premise that it was insurance against a flush that could
  not be resolved. The flush covers every transition, and a period-less
  flush only happens while the sink is being reset, so the premise does
  not hold.

- Ignore a flush that carries no period rather than reading it as "this
  item has no gain". Resetting to unity there would have been wrong if a
  bare flush ever arrived mid-playback; the test that pinned that
  behaviour now pins the opposite.

- Guard the pass-through branch against an empty input, which is the
  pipeline's own shared buffer and cannot be put into itself.

- The controller is written from the playback thread now, so its state
  updates and the recompute that follows them are synchronized rather
  than two independent volatile writes.

- Add ReplayGainSinkTest, which drives the real DefaultAudioSink and
  asserts it hands the processor the item being configured. That is the
  media3 behaviour this whole feature rests on, and it was previously
  asserted only by comments.
2026-10-16 13:07:07 +00:00
2021-08-23 14:48:24 +09:00
2022-06-20 19:01:25 +09:00

subtracks logo subtracks

f-droid github downloads Translation status license

subtracks is an open source Android client for Subsonic-compatible servers (Navidrome, gonic, LMS, Nextcloud Music and more). It is written natively in Kotlin and Jetpack Compose and gives you clean, convenient access to your music in the style of a modern media player.

Screenshots

home now playing albums album artist

Download

See signing/README.md for the fingerprints and the commands to verify a download.

Features

  • Large Libraries: Built for very large libraries, from syncing the whole collection to playing playlists with thousands of tracks.
  • Downloads: Song and bulk downloads, with download quality (encoding, bitrate) and metered-connection settings.
  • Offline Mode: Stars, scrobbles and play counts queue up while you're offline and sync back to the server when you're online again.
  • Artwork-first: Album and artist art everywhere, shown full-resolution in the detail and now playing views.
  • Adaptive Theming: Colours drawn from the current song's artwork.
  • Search: Fast search across the whole library, with per-list sort and filter controls.
  • Playback: Gapless playback, an editable queue you can reorder and jump through, plus loop and shuffle modes.
  • Up Next: Add items into the currently playing queue without rewriting it.
  • Multiple Servers: Connect several servers and switch between them quickly.
  • Stream Quality: Bitrate and format settings for Wi-Fi and mobile, with automatic switching.
  • System Controls: Media notification and headset/Bluetooth controls.

Building

The project's entire toolchain is provided by a Nix flake. The default devshell provides JDK, Gradle and the Android SDK, so there is nothing to install by hand.

Therefore, to get started, you'll need to install Nix. I prefer Lix.

nix develop
gradle :app:assembleDebug

Test, lint and screenshot commands, plus the integration harness, are documented in AGENTS.md. The architecture is described in docs/architecture.md.

Contributing

The GitHub repository austinried/subtracks is a mirror of the repo hosted on my personal (private) code forge that syncs whenever I commit to it.

Bug reports and feature requests are accepted on GitHub, as well as pull requests, but:

  • A well-crafted issue with clear reproduction and logs for bugs or mock-ups and use case details for features is preferred over a pull request
  • Pull requests will be pulled in as patches to my code forge and then synced back (you'll still be the author, I'll be shown as the committer)

Translations

Want to see subtracks in your language? Visit the project on Weblate to help!

Translation status

AI usage disclosure

This project contains code and documentation generated by LLM, which is created via human prompting, iteration and review. The current native rewrite is based on two (and a half) other iterations of this project that I coded by hand, so the architecture and other decisions behind that are all still coming from me.

License

subtracks is free software, licensed under the GNU General Public License v3.0. It has no ads and no telemetry, and uses only free/libre dependencies.

S
Description
A music streaming app for Subsonic-compatible servers
Readme GPL-3.0
58 MiB
Languages
Kotlin 99.1%
Nushell 0.7%
Nix 0.1%