Remove the about screen's reliance on the home data.
The home view's data can no longer be trusted now due to the "hide
collaborators" setting, so now the about screen uses statistics
derived from MusicStore itself. This also avoids constantly
resumming the duration when the UI is initially created.
Backport the code for full "Month + Year" dates to older versions with
the legacy Date API.
For the same of not missing bugs on newer devices, this is now what
will be used in Auxio.
Rework the music picker system to be a reactive, viewmodel-based system
instead of a janky UI system.
This should make it much easier to maintain and extend in the future.
Handle errors from databases.
Either way, a crash from a database or a silent error will be equally
nightmarish to debug. May as well keep going if they fail.
Try to move multi-artist playback/navigation into a single function.
This function is really bad and is tacked onto the most convienent
location without much thought. I really wish to move this into the
ViewModel flow eventually, but I have no idea how to architecture
that. Oh well.
Show a list of artists that contain songs from a particular genre in
the genre UI.
This used to be in really early Auxio versions, but was intertwined
with some really stupid genre functionality that would include songs
from an entire artist for some reason. Since now albums can be shown
in several artist entires, it makes no sense now what artists can't
be given the same treatment.
Make artist images sort by count instead of by name.
I've recently added a few singles in my library that have been
cluttering the previous artist image algorithm with non-ideal
covers. Instead of sorting by name (Which was really an artifact
of the old MediaStore engine anyway), sort by the amount of songs
of each album instead, which hopefully should weight images less
towards singles and more towards albums (And especially albums
the user likes).
Add a setting to hide "collaborators", that is artists that do not show
up on any album artist tags.
This is mostly for my own use since I don't get use from useless
collaborator entries.
If a song/album date has a month value, show it in the UI.
This hopefully improves the date experience for more well-tagged
libraries. Due to date limitations however, it is limited to
Android O onwards for now.
Unify the "Show Covers" and "Ignore MediaStore Covers" settings under an
new "Album covers" setting.
This will make it easier to extend to new forms of album cover
collection.
Add caching of already-parsed tag data.
This greatly reduces loading times when the music library has not
changed. This completes the music loader in it's entirety now.
Resolves#207.
Re-add parsing by escaped separators.
Previously I removed it becaue the regex parsing was not being
cooperative. Turns out we really do have to write our own parser
code. Fun.
Add a toggle to control the IS_MUSIC=1 selector.
This is normally used to remove non-music like podcasts and ringtones,
however some people use Auxio was a general-purpose audio player for
these files, so this setting can be used to disable that selector and
load non-music.
Resolves#246.
Use plural variants of vorbis artist/album artist tags.
Some people add these tags to signal the artist makeup of a song
when a player supports multiple artists while still allowing less
sophisticated players to operate with single-artist tags.
Add support for MusicBrainz IDs (MBIDs) in both grouping and UID
creation.
This should help with very large libraries where artist names
collide, thus requiring differentiation through other means. It also
theoretically opens the door to fetch online metadata, however I don't
really care for that and it would violate the non-connectivity promise
of Auxio.
Resolves#202.
Add semi-complete support for multiple artists.
This changeset completely reworks the music linker to add the following
new behaviors:
1. Artists are now derived from both artist and album artist tags,
with them being linked to songs and albums respectively
2. Albums and songs can now have multiple artists that can be distinct
from eachother
3. Previous Genre picking infrastructure has been removed and replaced
with artist picking infrastructure. "Play from genre" has been retired
entirely.
This is a clean break to the previous artist model and may not work
with all libraries. Steps to migrate the music library will be added
to the changelog.
Resolves#195.
Combine validation into a new finalization routine that now
individually validates and in the future may finalize certain
fields that require linking to be properly created.
Keep changes when unshuffling and reshuffling the queue.
This quirk was a hold-over from the old queue system, and now it's
removed.
Note that sorting is still based on parent, and so sort orders might
remain somewhat wonky. I only see myself really tackling that come
gapless playback, as I have to remove that last vestige to get that
system working.
Add a dialog for picking a genre from several choices.
This basically completes multi-genre support in Auxio, save more
internal reworks.
Note that it is extremely likely that the "Play from genre" setting
will be removed soon. This feature has made me realize that such does
not many any real sense, as genres are more semantically similar to
playlists than artists or albums. This implementation only exists to
make multi-artist support an easy plug-and-play operation.
Resolves#201
Add support for compilation + live, compilation + remix,
and compilation + dj-mix release types.
This was not included due to the changes it required to the
parser. Turns out these changes are largely trivial if I do
more clever inlining.
Make UID structure dependent on the music mode.
This involves replacing the "tag" value with more structured fields and
appending the int code of the music mode to the UUID rather than making
it part of the UID's "tag". UIDs aren't quite a UUID, so this is
allowed.
Merge DisplayMode and PlaybackMode into a new class called MusicMode.
Both of these datatypes represented similar things, and thus it's much
easier to make them the same datatype. Moreover, it makes the
forthcoming addition of the music selector much easier if the same
datatype was tied to the representation of music.
This commit also moves around things around the project to be slightly
more coherent.
Also take the size of the music file into account when it is being
played.
This way, we could remove some situations where two files with the
same name get confused with eachother when opened.
Use CollationKey when sorting music instead of String isntances.
This makes sorting aware of accented characters while still preserving
speed. I would ideally want to extend this to the search view too, but
there is no contains command in CollationKey, so I must continue with
the normalization method there.
Instead of updating the notif every 50 songs, update it every 1.5s.
This is in preparation for automatic reloading, which will once again
make Indexed song updates EXTREMELY fast and would thus rate-limit the
notification if the previous system was used.
Phase out the dumb hack TaskGuard class in favor of yield.
For some reason, I was under the impression that yield was horribly
slow. It's not, I was just using it wrong. So now TaskGuard is no
longer needed.
Re-add MediaStore genre parsing to the init() step.
This time, to play along with the new abstraction, the query is done in
initialization and loaded into a map that is then used when populating
raw audio.
Refactor all Backend instances into a new package called extractor and
a new structure called "Layer".
Layers are no longer generalized into an interface. Instead, they build
on eachother in order to produce a correct output of raw songs.
One of these layers is a stub class to eventually implement caching.
This changeset also phases out the "Ignore MediaStore tags" setting, as
it is no longer needed.
Add a basic framework for user-customizeable separators.
This is designed to be extendable if needed, albeit the app will likely
only let the user choose between +, ;, /, &, and ,.
Add separator parsing back, albeit in a much different manner.
Now Auxio will try to parse by , ; / + and &. This will be disabled by
default in the future and available as a setting. When parsing by
separator, whitespace is also trimmed. This occurs nowhere else though,
as there is no demand.
Add support for ID3v2.4-style multi-value tags separated by a null
terminator.
This temporarily removes most other forms of separator parsing in the
app. My plan is to reunify it under a new separator setting that allows
the user to select how multi-value tags are separated in their library.
Separator parsing tends to be too destructive by default, so this tends
to be a good option overall.
This commit does require ExoPlayer to be forked once again to add
ID3v2.4 separator support.
Fix some mistakes with the UID hashing process.
Some more work needs to be done regarding formalizing the datatype
and tagtype fields. If anything, I may just collapse them into a
single "tag" field since they are only used for equality.
Alternatively, I could make them integers to increase efficiency.
Depends.
Completely rework the ID system to pave the way to MusicBrainz ID
support and greatly increase ID integrity in general.
This changeset removes the old ID field, an emulation of a polynomial
hash that was used in all items, and replaces it with a new type called
UID that is specific to Music. Other types just use plain equals now,
and most instances of "id" to check for equality in the app have either
been inlined into an equals override or removed outright.
The new UID format is as follows:
datatype/format:uuid
Datatype is a tag that is just the lowercase tag name. For example,
"song". Format is the program that created the UID. auxio will be an
md5 hash, and musicbrainz will the a musicbrainz ID extracted from a
file. UUID is the uuid itself.
This is much more reliable and extendable than the old ID format. This
will also be the last time I break compat with old ID formats. From now
on, a legacy UID field will not be included to enable backwards compat,
when the time comes for a breaking change.
Add some functions to eventually enable multi-parent playback.
PlaybackMode is still used in some places, however will steadily be
phased out hopefully.
Migrate the playback system to a reactive model where internalPlayer
is now the complete source of truth for the playback state.
This removes the observer pattern for positions and instead introduces
a new State datatype that allows consumers to reactively calculate
where the position probably is.
This is actually really great for efficiency and state coherency, and
is really what I was trying to aim for with previous (failed) reworks
to the playback system. There's probably some bugs, but way less than
the ground-up rewrites I tried before.
This also lays the groundwork for gapless playback, as the internal
player framework is now completely capable of having more functionality
borged into it.
Fix a popup desynchronization issue in grid-based layouts.
This issue stemmed from the popup index calculation apparently not
needing a division by the span count in order to produce the correct
index. This kind of makes sense, but is still really weird.
Resolves#230.
Add basic support for multiple genres.
This is sort of the test run for full multi-artist support, allowing me
to rework my abstractions to handle the presence of multiple parents.
This is nowhere near complete. For example, there is currently a stopgap
measure in the playback system that basically breaks genre playback.
It's a start though.
Make adapter instances handle span sizes.
This supercedes the hackier solution where the fragments would have to
reference adapter data in order to determine span size. Not anymore.
Make the playing indicator animate when playback is ongoing.
Previously state issues stopped me from doing this, but apparently this
time I miraculously got it working. Yay.
Resolves#218.
Revert the song menu in the playback panel to being in the toolbar.
It was mostly inconsistent and cause a lot of truncation. I'll figure
out what I want to do when I implement liked songs.
Add a fast scroller to the queue view.
This is actually easy to implement without disruption. Now the detail
view is the only view without such a fast scroller, as it needs more
reworks for it to be feasible.
Switch position math to rely on deciseconds (1/10th of a second)
instead of full seconds.
This makes seeking and position management much smoother, with minimal
performance cost. In the future I may try to migrate the playback state
so that the position calculations are done on the UI end, but this
works for now.
Make the thumb visible if a popup provider is found later.
Fixes an issue where the fast scroll thumb would only be visible
sometimes in the home view.
Make PlaybackService handle delayed actions.
I wanted to do this before, but technical limitations always
stopped me from doing so. Turns out all I needed was a dash
of global mutable state to make it all work. This is actually
really good, as it separates concerns better and paves the way
for future improvements to the service.
Make the shape of the play/pause buttons throughout the app morph from
a circle if paused to a square if playing.
Android 13 seemingly does this to their play/pause button, so we copy
it too.
Tangentally related to #162.
Do not check for the version when managing the notification.
Some OEMs will update the android system, causing the version number to
change, but will THEN not update the system UI, completely breaking my
compat hacks. Because you know. Reasons. Fix this by always applying
future and obsolete methods of updating the media notification
regardless of the context.
Resolves#219.
Migrate MediaSessionComponent to android 13.
This was primarily implementing custom actions with the media session
and adding some extra bug fixes that I was already planning. I was
really hoping that google fixes the nightmarish mess that was the
previous MediaStyle notification, where I had to update the session
and then the notification in a tight dance with clever tricks to not
get rate-limited, but nope. I still have to do exactly the same thing
as beforehand, but with even extra insanity due to the custom actions.
Work aroudn an issue in Android 13 where bitmap pooling would not work
correctly and reduce our max memory limit by ~10x.
When I mean work around, I mean that we reduce the size of the rounded
covers further to ensure we aren't hitting the memory limit. This also
sadly blocks us from further RemoteViews instances, as the bugged
memory size will continue to increase if we do that.