From 5764c19801627fc97ac981e09df60afb336ed283 Mon Sep 17 00:00:00 2001 From: Alexander Capehart Date: Wed, 28 Dec 2022 14:45:22 -0700 Subject: [PATCH] info: retire info documents Retire the old information documents in favor of the new wiki. --- README.md | 2 +- .../java/org/oxycblt/auxio/MainActivity.kt | 2 + .../auxio/detail/AlbumDetailFragment.kt | 1 - .../auxio/playback/PlaybackViewModel.kt | 2 +- .../auxio/playback/queue/QueueFragment.kt | 3 +- .../org/oxycblt/auxio/settings/Settings.kt | 2 +- .../org/oxycblt/auxio/ui/AuxioAppBarLayout.kt | 3 +- info/ADDITIONS.md | 21 -- info/ARCHITECTURE.md | 348 ------------------ info/FAQ.md | 127 ------- info/LICENSES.md | 13 - 11 files changed, 8 insertions(+), 516 deletions(-) delete mode 100644 info/ADDITIONS.md delete mode 100644 info/ARCHITECTURE.md delete mode 100644 info/FAQ.md delete mode 100644 info/LICENSES.md diff --git a/README.md b/README.md index 4eb21f9f1..edf642ed3 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Minimum SDK Version

-

Changelog | FAQ | Licenses | Contributing | Architecture

+

Changelog | Wiki

Translation status diff --git a/app/src/main/java/org/oxycblt/auxio/MainActivity.kt b/app/src/main/java/org/oxycblt/auxio/MainActivity.kt index 267e98cc3..f33f9d2b1 100644 --- a/app/src/main/java/org/oxycblt/auxio/MainActivity.kt +++ b/app/src/main/java/org/oxycblt/auxio/MainActivity.kt @@ -54,6 +54,8 @@ import org.oxycblt.auxio.util.systemBarInsetsCompat * * TODO: Standardize companion object usage * + * TODO: Standardize callback/listener naming. + * * @author Alexander Capehart (OxygenCobalt) */ class MainActivity : AppCompatActivity() { diff --git a/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt index 86efe4cd6..1d3d4f9f3 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt @@ -244,7 +244,6 @@ class AlbumDetailFragment : ListFragment(), AlbumDetailAd binding.detailRecycler.post { // Use a custom smooth scroller that will settle the item in the middle of // the screen rather than the end. - // TODO: Can I apply this to the queue view? val centerSmoothScroller = object : LinearSmoothScroller(context) { init { diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt index 14b668428..d2e5e4181 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt @@ -284,7 +284,7 @@ class PlaybackViewModel(application: Application) : * @param song The [Song] to add. */ fun playNext(song: Song) { - // TODO: Queue additions without a playing song should map to queued items + // TODO: Queue additions without a playing song should map to playing items // (impossible until queue rework) playbackManager.playNext(song) } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueFragment.kt b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueFragment.kt index b5f9288db..9dfbc9962 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueFragment.kt @@ -88,6 +88,7 @@ class QueueFragment : ViewBindingFragment(), QueueAdapter. queueModel.finishReplace() // If requested, scroll to a new item (occurs when the index moves) + // TODO: Scroll to center/top instead of bottom val scrollTo = queueModel.scrollTo if (scrollTo != null) { // Do not scroll to indices that are in the currently visible range. As that would @@ -102,7 +103,7 @@ class QueueFragment : ViewBindingFragment(), QueueAdapter. } queueModel.finishScrollTo() - // Update currently playing item + // Update position in list (and thus past/future items) queueAdapter.setPosition(index, isPlaying) } } diff --git a/app/src/main/java/org/oxycblt/auxio/settings/Settings.kt b/app/src/main/java/org/oxycblt/auxio/settings/Settings.kt index 7bd6d6b92..18beeddc8 100644 --- a/app/src/main/java/org/oxycblt/auxio/settings/Settings.kt +++ b/app/src/main/java/org/oxycblt/auxio/settings/Settings.kt @@ -165,7 +165,7 @@ class Settings(private val context: Context, private val callback: Callback? = n unlikelyToBeNull(callback).onSettingChanged(key) } - /** TODO: Remove this */ + /** TODO: Rework this */ interface Callback { fun onSettingChanged(key: String) } diff --git a/app/src/main/java/org/oxycblt/auxio/ui/AuxioAppBarLayout.kt b/app/src/main/java/org/oxycblt/auxio/ui/AuxioAppBarLayout.kt index b6bd8ca79..91e122dad 100644 --- a/app/src/main/java/org/oxycblt/auxio/ui/AuxioAppBarLayout.kt +++ b/app/src/main/java/org/oxycblt/auxio/ui/AuxioAppBarLayout.kt @@ -73,8 +73,7 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr * @param recycler [RecyclerView] to expand with, or null if one is currently unavailable. */ fun expandWithRecycler(recycler: RecyclerView?) { - // TODO: Is it possible to use liftOnScrollTargetViewId to avoid the [RecyclerView] - // argument? + // TODO: Is it possible to use liftOnScrollTargetViewId to avoid the RecyclerView arg? setExpanded(true) recycler?.let { addOnOffsetChangedListener(ExpansionHackListener(it)) } } diff --git a/info/ADDITIONS.md b/info/ADDITIONS.md deleted file mode 100644 index 5c634941c..000000000 --- a/info/ADDITIONS.md +++ /dev/null @@ -1,21 +0,0 @@ -# Accepted Additions and Requests -One of the reasons I built Auxio was out of frustration with other FOSS android music players, which had too many features, frustrating UI/UX flaws, or both. Therefore any additions will have to be accepted by **me** (OxygenCobalt) before they are implemented or merged. - -## Bug Fixes, Optimizations, Architecture Improvements, etc. -These will likely be accepted as long as they do not cause too much harm to the codebase. - -## New Customizations/Options -While I do like adding new behavior/UI customizations, these will be looked at more closely as certain additions can cause harm to the apps UI/UX while not providing a lot of benefit. These tend to be accepted however. - -## Feature Additions and UI Changes -These arent as likely to be accepted. As I said, I do not want Auxio to become overly bloated with features that are rarely used, therefore I only tend to accept features that: -- Benefit **my own** usage -- Are in line with Auxio's purpose as a music player - -This does not rule out these additions, but they are not accepted as often as others. I will also hold off adding features until I'm able to implement them without disruption or strange behaviors. - -Feel free to fork Auxio to add your own feature set however. - -## Additions that have already been rejected - -To see an up-to-date list on all of the features that have been rejected, see [this link](https://github.com/OxygenCobalt/Auxio/issues?q=label%3Awontadd-technical%2Cwontadd-out-of-scope+) \ No newline at end of file diff --git a/info/ARCHITECTURE.md b/info/ARCHITECTURE.md deleted file mode 100644 index 38f1353e8..000000000 --- a/info/ARCHITECTURE.md +++ /dev/null @@ -1,348 +0,0 @@ -# Architecture -This document is designed to provide an overview of Auxio's architecture and design decisions. It -will be updated as Auxio changes, however it may not completely line up as parts of the codebase -will change rapidly at times. - -## Core Facets -Auxio has a couple of core systems or concepts that should be understood when working with the -codebase. - -#### Package Structure -Auxio is deliberately structured in a way that I call "Anti-CLEAN Architecture". There is one -gradle project, with sub-packages that are strictly feature-oriented. For example, playback code is -exclusively in the `playback` package, and detail code is exclusively in the `detail` package. -Sub-packages can be related to the code it contains, such as `detail.recycler` for the detail UI -adapters, or hey can be related to a sub-feature, like `playback.queue` for the queue UI. - -The outliers here are `.ui` and `.util`, which are generic utility or component packages. - -Sticking to a single project reduces compile times, makes it easier to add new features, and simply -makes Auxio's code better to reason about since you don't have to jump across disparately related -gradle projects. - -A full run-down of Auxio's current package structure as of the latest version is shown below. - -``` -org.oxycblt.auxio # Main UIs -├──.detail # Album/Artist/Genre detail UIs -│ └──.recycler # RecyclerView components for detail UIs -├──.home # Home UI -│ ├──.fastscroll # Fast scroller UI -│ ├──.list # Home item lists -│ └──.tabs # Home tab customization -├──.image # Image loading components -├──.music # Music data and loading -│ ├──.dirs # Music folders UI + systems -│ └──.system # Internal music loading -├──.playback # Playback UI + Systems -│ ├──.queue # Queue UI -│ ├──.replaygain # ReplayGain System + UIs -│ ├──.state # Playback state backend -│ └──.system # System-side playback [Services, ExoPlayer] -├──.search # Search UI -├──.settings # Settings UI + Systems -│ └──.ui # Preference extensions -├──.ui # Custom android components -│ ├──.accent # Color Scheme UI + Systems -│ ├──.fragment # Fragment extensions -│ ├──.recycler # RecyclerView extensions -│ └──.system # System-side components -├──.util # Shared utilities -└──.widgets # AppWidgets -``` - -Each package is gone over in more detail later on. - -#### UI Structure -Auxio only has one activity, `MainActivity`. Do not try to add more activities to the codebase. -Instead, a new UI should be added as a new `Fragment` implementation and added to one of the two -navigation graphs: - -- `nav_main`: Navigation *from* `MainFragment` -- `nav_explore`: Navigation *in* `MainFragment` - -Fragments themselves are based off several extensions that enable extra functionality, such as -ViewBinding or safe `PopupMenu` creation. - -Generally: -- Most variables are kept as member variables, and cleared out when the view is destroyed. -- Observing data is done through the `Fragment.launch` extension, and always points to another -function in order to reduce possible memory leaks. -- When possible (and readable), `Fragment` implementations inherit any listener interfaces they -need, and simply clear them out when done. - -`findViewById` is to **only** be used when interfacing with non-Auxio views. Otherwise, view-binding -should be used in all cases. Code that involves retrieving the binding should be isolated into its -own function, with the binding being obtained by calling `requireBinding`. - -At times it may be more appropriate to use a `View` instead of a fragment. This is okay as long as -view-binding is still used. - -Auxio uses `RecyclerView` for all list information. To manage some complexity, there are a few -conventions that are used when creating adapters. These can be seen in the `RecyclerFramework` -file and in adapter implementations. - -#### Object communication -Auxio's codebase is mostly centered around 4 different types of code that communicates with -each-other. - -- UIs: Fragments, RecyclerView items, and Activities are part of this class. All of them should have -little data logic in them and should primarily focus on displaying information in their UIs. -- ViewModels: These usually contain data and values that a UI can display, along with doing data -processing. The data ten takes the form of `MutableStateFlow` or `StateFlow`, which can be observed. -- Services: Auxio's services are intended to perform some kind of long-running task, while driving -the Shared Object related to the work that they are doing. -- Shared Objects: These are the fundamental building blocks of Auxio, and exist at the process -level. These are usually retrieved using `getInstance` or a similar function. Usually, methods in -these are also Synchronized to prevent issues with global/mutable/concurrent state. Shared Objects -should be avoided in UIs, as their volatility can cause problems. Its better to use a ViewModel -and their exposed data instead. -- Utilities: These are largely found in the `.util` package, taking the form of standalone or -extension functions that can be used anywhere. - -Ideally, UIs should only be talking to ViewModels, ViewModels and Services should only be talking -to the Shared Objects, and Shared Objects should only be talking to other shared objects. All -objects can use the utility functions where appropriate. - -#### Data objects -Auxio represents data in multiple ways. - -`Item` is the base class for most music and UI data in Auxio, with a single ID field meant to mark it as unique. - -It has the following implementations: -- `Music` is a `Item` that represents music. It adds a `name` field that represents the raw name -of the music (from `MediaStore`), and a `resolveName` method meant to resolve the name in context -of the UI. -- `MusicParent` is a type of `Music` that contains children. -- `Header` corresponds to a simple header with a title and no interaction functionality. There are -also the `detail`-specific `DiscHeader` and `SortHeader`, however these are largely unrelated to -`Header`. - -Other data types represent a specific UI configuration or state: -- Data structures like `Sort` contain an ascending state that can be modified immutably. -- Enums like `MusicMode` and `RepeatMode` only contain static data, such as a string resource. - -Things to keep in mind while working with music data: -- `id` is not derived from the `MediaStore` ID of the music data. It is actually a hash of the -unique, non-subjective fields of the music data. Attempting to use it as a `MediaStore` ID will -result in errors. -- Any field or method beginning with `_` is off-limits. These fields are meant for use within -the indexer and generally provide poor UX to the user. The only reason they are public is to -simplify the loading process, as there is no reason to remove internal fields given that it won't -free memory. -- `rawName` is used when doing internal work, such as saving music data or diffing items -- `sortName` is used in the fast scroller indicators and sorting. Avoid it wherever else. -- `resolveName()` should be used when displaying any kind of music data to the user. -- For songs, `individualArtistRawName` and `resolveIndividualArtistName` should always be used when -displaying the artist of a song, as it will always show collaborator information first before -defaulting to the album artist. - -#### Music Access -Whereas other apps load music from `MediaStore`, Auxio does not do that, as it prevents any kind of -reasonable metadata functionality (ex. Album Artists). Instead, Auxio loads all music into an -in-memory relational construct called `Library`. - -`Library` is obtained from `MusicStore`, however since Auxio's music loading is asynchronous and -can occur several times over the runtime of the app, it is highly recommended for code to rely -on `MusicStore.Callback`. In the case that a piece of code would only be ran if there was a library, -`requireNotNull` can be used, however this is highly risky. - -Since Shared Objects should not be attached to the Callback system of another Shared Object, it -is highly recommended to check for the existence of a `Library` if required, and no-op if it was -not available. - -Monitoring the loading progress (Internally called the indexing state) should be done sparingly, -and is best done with `MusicViewModel`. - -#### Playback System -The android/androidx media state APIs are poorly designed, and are often the cause of the strange queue -behavior and jank you see in other apps. So, Auxio does not use it, instead implementing it's own -playback engine that is more controllable and sensible and simply mirroring it to the android APIs. - -The diagram below highlights the overall structure and connections: - -``` - ┌──────────────────── PlaybackService - │ │ -PlaybackStateManager [Communicates with] │ - │ │ [Controls] - │ │ - │ ├ WidgetComponent - │ ├ NotificationComponent - │ ├ MediaSessionComponent - │ └ Player - │ - │ - └──────────────────── PlaybackViewModel ───────────────────── UIs - [Controls] -``` - -`PlaybackStateManager` is the shared object that contains the master copy of the playback state, -doing all operations on it. This object should ***NEVER*** be used in a UI, as it does not sanitize -input and can cause major problems if a Volatile UI interacts with it. It's callback system is also -prone to memory leaks if not cleared when done. - -For UIs, `PlaybackViewModel` exists instead. It provides safe, observable data and abstractions to -make managing the playback state simple from the UI. - -`PlaybackService`'s job is to use the playback state to manage the ExoPlayer instance, the -notification, the media session, the widget, and also modify the state depending on system events, -such as when a button is pressed on a headset. It should **never** be bound to, mostly because -there is no need given that `PlaybackViewModel` exposes the same data in a much safer fashion. - -#### Data Integers -Integer representations of data/UI elements are used heavily in Auxio, primarily for efficiency. To -prevent any strange bugs, all integer representations must be unique. To see a table of all current -integers, see the `IntegerTable` class within the project. - -Some datatypes [like `Tab` and `Sort`] have even more fine-grained integer representations for other -data. More information can be found in the documentation for those datatypes. - -## Package-by-package rundown - -#### `org.oxycblt.auxio` -This is the root package and contains the application instance and the landing UIs. This should be -kept sparse with most other code being placed into a package. - -#### `.detail` -Contains all the detail UIs for some data types in Auxio. All detail user interfaces share the same -base layout (A Single RecyclerView) and only change the adapter/data being used. The adapters -display both the header with information and the child items of the item itself, usually with a data -list similar to this: - -`Item being displayed | Header Item | Child Item | Child Item | Child Item...` - -Note that the actual dataset used is more complex once sorting and disc numbers is taken into -account. - -#### `.home` -This package contains the components for the "home" UI in Auxio, or the UI that the user first sees -when they open the app. - -- The base package contains the top-level components that manage the FloatingActionButton, AppBar, -and ViewPager instances. -- The `fastscroll` package contains the fast scroll component used in each list of music -- The `list` package contains the individual fragments for each list of music. These are all placed -in the top-level ViewPager instance. -- The `tabs` package contains the data representation of an individual library tab and the UIs for -editing them. - -#### `.image` -[Coil](https://github.com/coil-kt/coil) is the image loader used by Auxio. This package contains the -components Auxio leverages to load images in a stable manner. Usually, you do not need to import -this package elsewhere, but there are some important components: - -- `BitmapProvider`, which allows external components (Such as in PlaybackService) to load a `Bitmap` -in a way not prone to race conditions. This should not be used for UIs. -- `BaseFetcher`, which is effectively Auxio's image loading routine. Most changes to image loading -should be done there, and not it's sub-classes like `AlbumArtFetcher`. - -This package also contains the two UI components used for all covers in Auxio: -- `StyledImageView`, which adds extensions for dynamically loading covers, handles rounded corners, -and a stable icon style. -- `ImageGroup`, an extension of `StyledImageView` that all of the previous features, alongside a -playing indicator and one custom view. - -#### `.music` -This package contains all `Music` implementations, the music loading implementation, and the music -folder system. This is the second most complicated package in the app, as loading music in a sane -way is quite difficult. - -The major classes are: -- `MusicStore`, which is the container for a `Library` instance. Any code wanting to access the -library should use this. -- `Indexer`, which manages how music is loaded. This is only used by code that must manage or -mirror the music loading state. -- The extractor system, which is Auxio's music parser. It's structured as several "Layer" classes -that build on eachother to implement version-specific functionality. - -Internally, there are several other major systems: -- `IndexerService`, which does the indexer work in the background. -- `StorageFramework`, which is a group of utilities that allows Auxio to be volume-aware and to -work with both extension-based and format-based mime types. -- Configuration models like `MusicMode` and `Sort`, which are tangentally related to operations -done on music - -The music loading process is roughly as follows: -1. Something triggers `IndexerService` to start indexing, either by the UI or by the service itself -starting. -2. `Indexer` picks an appropriate `Backend`, and begins loading music. `Indexer` may periodically -update it's state during this time with the current progress. -3. In the case that `IndexerService` is killed, `Indexer` falls back to a previous state (or null -if there isn't one). -4. If the music loading process completes, `Indexer` will push a `Response`. `IndexerService` will -read this, and in the case that the new `Library` differs, it will push it to `MusicStore`. -5. `MusicStore` updates any `Callback` instances with the new `Library`. - -#### `.playback` -This module not only contains the playback system described above, but also multiple other -components: - -- `queue` contains the Queue UI and it's fancy item system. -- `replaygain` contains the ReplayGain implementation and the UIs related to it. Auxio's ReplayGain -implementation is somewhat different compared to other apps, as it leverages ExoPlayer's metadata -and audio processing systems to not only parse ReplayGain tags, but also allow volume amplification -above 100%. -- `state` contains the core playback state and persistence system. -- `system` contains the system-facing playback system, i.e `PlaybackService`. - -The base package contains the user-facing UIs representing the playback state, specifically the -playback bar and the playback panel that it expands into. Note that while the playback UI does rely -on `BottomSheetLayout`, the layout is designed to be at least somewhat re-usable, so it is in the -generic `.ui` class. - -#### `.search` -Package for Auxio's search functionality, `SearchViewHolder` handles the data results and filtering -while `SearchFragment`/`SearchAdapter` handles the display of the results and user input. - -#### `.settings` -The settings system is primarily based off of `Settings`, a type-safe wrapper around -`SharedPreferences`. `Settings` is not a shared object, but actually a utility instantiated -with a `Context`. Thus, the way to leverage them differs depending on if the code is in a UI, -ViewModel, Shared Object, or Service. - -Internally, the settings package also leverages a couple custom preference implementations, -notably `IntListPreference`, which enables a normal choice preference to be backed by the -integer data that Auxio uses. - -#### `.ui` -Shared views and view configuration models. This contains: - -- Important `Fragment` superclasses like `ViewBindingFragment` and `MenuFragment` -- Customized views such as `AuxioAppBarLayout`, and others, which fix shortcomings with the -default implementations. -- `ForegroundManager` and `ServiceNotification`, which remove boilerplate regarding service -foreground instantiation. -- The `RecyclerView` adapter framework described previously. -- `BottomSheetLayout`, which implements a bottom sheet in a way that is not completely broken. -- Standard `ViewHolder` implementations that can be used for common datatypes. -- `NavigationViewModel`, which acts as an interface to control navigation to a particular item and -navigation within `MainFragment` - -#### `.util` -Shared utilities. This is primarily for QoL when developing Auxio. Documentation is provided on each method. - -Utilities are separated into a few groups: -- Context utilities are extensions of `Context` and generally act as shortcuts for that class. -- Framework utilities extend a variety of view implementations to add new behavior or shortcuts. -- Primitive utilities operate on basic datatypes and are mostly shortcuts. -- Log utilities are a more light-weight logging framework that Auxio leverages instead of -bloated and over-engineered libraries like Timber. - -#### `.widgets` -This package contains Auxio's AppWidget implementation, which deviates from other AppWidget -implementations by packing multiple different layouts into a single widget and then switching -between them depending on the widget size. Note that since `RemoteViews` and the AppWidget API -in general is incredibly outdated and limited, this package deviates from much of Auxio's normal UI -conventions. - -PlaybackService owns `WidgetComponent`, which listens to `PlaybackStateManager` for updates. During -an update, it reloads all song metadata and playback state into a `WidgetState`, which is an -immutable version of the playback state that negates some of the problems with using a volatile -shared object. - -`WidgetProvider` is the widget "implementation" exposed in the manifest. When `WidgetComponent` -updates it, the class will create a series of layouts [e.g "Forms"] for a variety of "size buckets" -that would adequately contain the widget. This is then used as the widget views, either with the -native responsive behavior on Android 12 and above, or with the responsive behavior back-ported -to older devices. diff --git a/info/FAQ.md b/info/FAQ.md deleted file mode 100644 index bac1c9621..000000000 --- a/info/FAQ.md +++ /dev/null @@ -1,127 +0,0 @@ -# Auxio - Frequently Asked Questions -This FAQ will be continually updated as new changes and updates are made to Auxio. - -#### Where can I download Auxio? -Auxio is available on the [F-Droid](https://f-droid.org/en/packages/org.oxycblt.auxio/) repository. -Auxio is not and will never be on the play store due to it being a proprietary and draconian platform. - -#### Why ExoPlayer? -Unlike the stock `MediaPlayer` API that most music apps use, ExoPlayer is independent from the android system's -audio framework. This allows for the following: -- Consistent behavior across devices and OS versions -- Features that are normally not possible with a normal audio stream (such as positive ReplayGain values) -- Playback to be (theoretically) be extended beyond local files in the future - -You can read more about the benefits (and drawbacks) of ExoPlayer [Here](https://exoplayer.dev/pros-and-cons.html). - -#### What formats does Auxio support? -As per the [Supported ExoPlayer Formats](https://exoplayer.dev/supported-formats.html), Auxio supports -MP4, MP3, MKA, OGG, WAV, MPEG, AAC on all versions of Android. Auxio also supports FLAC on all versions -of Android through the use of the ExoPlayer FLAC extension. - -#### Why doesn't Auxio have a built-in equalizer or tag editor? - -Auxio tends to abide by a unix-esque philosophy where programs should try to stay in one -category of tasks and do those tasks well. - -- For equalization, Android already supports external equalizers like Wavelet, which tend to -work on most modern devices that don't have broken OEM software. This is generally preferred -compared to implementing my own equalizer. -- For tag editing, external programs like kid3, picard, or ex falso fill this role. - -#### Auxio doesn't load my music correctly! -This depends on the context: -1. If "Ignore MediaStore Tags" is enabled, please create a bug report. -2. If "Ignore MediaStore Tags" is not enabled, please check below to make sure your issue is not already -acknowledged before reporting a bug. - - Moreover, if the issue encountered does not appear in other apps like Music Player GO, Phonograph, -or Retro Music then it should definitely be reported, as it is a logic bug on Auxio's part. - -***Known unfixable music loading issues*** - -These are a list of unfixable music loading issues that can only be fixed by enabling "Ignore MediaStore Tags": - -**My FLAC/OGG/OPUS/MP3 files don't have dates:** Android does not read the `DATE` tag from vorbis files. It reads the `YEAR` tag. -Similarly, Android does not read ID3v2.4's `TDRC` and actually reads `TYER` regardless of the version. This is because android's -metadata parser is stuck in 2008. - -**Some files with accented/symbolic characters have corrupted tags:** When Android extracts metadata, at some point it tries to convert the bytes it extracted to a -java string, which apparently involves detecting the encoding of the data dynamically and then converting it to Java's Unicode dialect. Of course, trying to detect -codings on the fly like that is a [bad idea](https://en.wikipedia.org/wiki/Bush_hid_the_facts), and more often than not it results in UTF-8 tags (Seen on -FLAC/OGG/OPUS files most often) being corrupted. It also affects MP3 files with ID3v2.4.0 tags that use the UTF-8 encoding in text-based tags. - -**I have a large library and Auxio takes really long to load it:** This is expected since reading from the audio database takes awhile, especially with libraries -containing 10k songs or more. - -**Auxio does not detect disc numbers:** If your device runs Android 10, then Auxio cannot parse a disc from the media database due to -a regression introduced by Google in that version. If this issue appears in another android version, please file an issue. - -***Other music loading issues*** - -**There should be one artist, but instead I get a bunch of "Artist & Collaborator" artists:** This likely means your tags are wrong. By default, Auxio will use the -"album artist" tag for grouping if present, falling back to the "artist" tag otherwise. If your music does not have such a field, it will result in fragmented artists. -The reason why Auxio does not simply parse for separators and then extract artists that way is that it risks mangling artists that don't actually have collaborators, -such as "Black Country, New Road" becoming "Black Country". I understand that some users may leverage MusicBrainz tags that enable a song to be referenced by several -artists, but such functionality in Auxio will likely take awhile to implement to to UI and technical constraints. - -**Auxio does not detect new music:** This is Auxio's default behavior due to limitations regarding android's filesystem APIs. To enable such behavior, turn on -"Automatic reloading" in settings. Note that this option does require a persistent notification and higher battery usage. - -#### What does "Ignore MediaStore Tags" even do? -"Ignore MediaStore Tags" configures Auxio's music loader to extract metadata manually using ExoPlayer, which enables the following: -- Fixes for most of the annoying, unfixable issues with `MediaStore` that were elaborated on above -- Sort tag support - - For example, a title written in Japanese could have a phonetic version in their sort tags. This will be used in sorting and search. -- Better date support - - If an artist released several albums in a single year, you can tag your music to have a particular date and time it was released on, and Auxio will - sort the albums accordingly. Examples include `YYYY-MM-DD` or even `YYYY-MM-DD HH:MM:SS` - - Auxio is also capable of supporting original dates. If a remastered album was released in 2020, but the original album was released in 2000, - you can tag your music with `TDOR`/`TORY` for MP3 and `ORIGINALDATE` for Vorbis with the year 2000, and Auxio will display 2000 in-app. -- Release type support from `TXXX:MusicBrainz Release Type`/`GRP1` in MP3 files, and `RELEASETYPE` in OGG/OPUS/FLAC - - Auxio specifically expects something formatted like ` + `, ``, or ``. This should be contained in a single tag. - - ` corresponds to `album`, `ep`, or `single` - - `` corresponds to `compilation`, `soundtrack`, `mixtape`, `live`, or `remix`. The first three will override the primary type, - (ex. `album + compilation` -> "Compilation"), but the latter two will be used to augment the primary type (ex. `album + live` -> "Live Album"). - -#### Why does search return songs that don't match my query? -Auxio actually takes several types of metadata in account in searching: -- The name, normalized so that any accented/symbolic characters are converted to normal characters. For example, Ü -> U. -- The sort tag of a particular song/album/artist, as such often contain latinized/translated versions of a given title. -- The file name, as some users don't have usable title metadata, and instead use the file name as the title. - -#### Why does playback pause whenever music is reloaded? -Whenever the music library significantly changes, updating the player's data while it is still playing may result in -unwanted bugs or unexpected music playing. To safeguard against this, Auxio will pause whenever it reloads a new -music library. - -#### ReplayGain isn't working on my music! -This is for a couple reason: -- Auxio doesn't extract ReplayGain tags for your format. This is a problem on ExoPlayer's end and should be -investigated there. -- Auxio doesn't recognize your ReplayGain tags. This is usually because of a non-standard tag like ID3v2's `RVAD` or -an unrecognized name. - -#### My lossless audio sounds lower-quality in Auxio! -This is a current limitation with the ExoPlayer. Basically, all audio is downsampled to 16-bit PCM audio, even -if the source audio is higher quality. I can enable something that might be able to remedy such, but implementing it -fully may take some time. - -#### Why is playback distorted when I play my FLAC/WAV files? -ExoPlayer, while powerful, does add some overhead when playing exceptionally high-quality files (2000+ KB/s bitrate, -90000+ Hz sample rate). This is worsened by the ReplayGain system, as it has to copy the audio buffer no matter what. -This results in choppy, distorted playback in some cases as audio data cannot be delivered in time. I can also mitigate -this similarly to the above issue, but again, it may take some time. - -#### Why are accents lighter/less saturated in dark mode? -As per the [Material Design Guidelines](https://material.io/design/color/dark-theme.html), accents should be less -saturated on dark mode to reduce eye strain and to increase visual cohesion. - -#### Does this app keep/send any information about myself or my device? -Auxio does not log any information about the device or its owner, and it has no internet access to send that information off in the first place. - -#### How can I contribute/report issues? -Open an [Issue](https://github.com/OxygenCobalt/Auxio/issues) or a [Pull Request](https://github.com/OxygenCobalt/Auxio/pulls), -please note the [Contribution Guidelines](../.github/CONTRIBUTING.md) and [Accepted Additions](ADDITIONS.md) however. - -#### Can I translate Auxio to my native language? -Please go to Auxio's [Weblate Project](https://hosted.weblate.org/engage/auxio/) to create new translations for the project. diff --git a/info/LICENSES.md b/info/LICENSES.md deleted file mode 100644 index e7d347ae9..000000000 --- a/info/LICENSES.md +++ /dev/null @@ -1,13 +0,0 @@ -# Licenses - -Auxio is licensed under the GPLv3. - -Alongside this, Auxio uses a number of third-party libraries. These are listed below with -their licenses: - -| Library Name | Author(s) | Purpose | License | -|-----------------------------------------------------|----------------------------------------------|----------------|------------| -| [ExoPlayer](https://github.com/google/ExoPlayer) | [Google](https://github.com/google) | Music Playback | Apache-2.0 | -| [Coil](https://github.com/coil-kt/coil) | [Square](https://github.com/coil-kt) | Image Loading | Apache-2.0 | -| [Spotless](https://github.com/diffplug/spotless) | [DiffPlug](https://github.com/diffplug) | Formatting | Apache-2.0 | -| [ktfmt](https://github.com/facebookincubator/ktfmt) | [Meta](https://github.com/facebookincubator) | Formatting | Apache-2.0 |