- Settle on a model I am satisfied with for multi Koto Libraries and implement it. All of it.
- Implement per-Playlist settings such as randomization and model (moving that out of the database too).
- Implement a Solarized built-in theme, since that is a fairly popular stylistic choice. I would love to hear your ideas on additional themes too, even silly / fun ones!
koto_cartographer_get_library_by_uuid
koto_cartographer_get_library_containing_path
koto_cartographer_get_libraries_for_storage_uuid
koto_cartographer_get_libraries
koto_album_get_uuid
, which returns a pointer to the KotoAlbum's UUID, which is consistent with other classes / structs we have like Artist, Playlist, and Track. This function gets used for sanity checking in Cartographer, so when we add an Album we actually make sure we don't add it when it already exists. It is additionally used in some of our Artist code and file indexer.
Once this was done, I separated out our functions responsible for reading from our database tables, moving it to reside in the same section of our codebase as Cartographer and our database helper functions. This helped clean up the library code so it would not be so unwieldy to refactor, cleanup, and mentally parse.
For several weeks after that, I was hard at work on our new multi-Library functionality. In Dev Diary 9, I mentioned that was still working on determining the best model for implementing indexing and organizing content across libraries. I am fairly happy with the current implementation, though there is always room for improvement, so time to detail the direction I opted to take.
The biggest changes to our folder and file indexing was the refactoring of the file indexing logic into a dedicated file indexing function. While this may not sound exciting, it is worth noting that this functionality was previously specific to Koto Albums. Obviously this poses a problem for content which have no albums and in scenarios where we may have music directly within a specific folder that we may associated with an artist, but in reality can by any arbitrary content, e.g. royalty free holiday music in specific folders that would otherwise be treated as artists. In scenarios where we have multiple CDs within an album, this code was added as another "depth" checking in our folder indexing function, whereas previously it was also in the Album.
To aid in simplifying the logic for our file indexing as well as track sorting, I implemented several functions:
koto_track_helpers_get_name_for_file
: This function takes in the full path to the file as well as an optional name of an artist. We will attempt to get the ID3 information for the file and if successful, return the "title" tag provided by the metadata assuming it is a correct string. If it is not a valid string or we failed to get ID3 information, we use our previous file indexing logic we had in the album to clean up the file name, including removing the name of the artist, hyphens, extra spaces, etc.koto_track_helpers_get_position_based_on_file_name
: This function will attempt to get the position of the track based on its file name. This existed previously as a "koto util" but was moved to a more sensible location for consistency.- Multiple sorting functions such as
koto_track_helpers_sort_tracks_by_uuid
aid in reducing duplicate track sorter code. This sorting logic saw substantial cleanup, type checking, and simplification as well, so I am in a much happier place with how we perform sorting, and it is done in a manner that is consistent across the application.
XDG_MUSIC_DIR
, another Library at a different mount point, and yet another on a removal storage? Also not a problem.
Each of the paths for our Artists, Albums, and Tracks are stored in dedicated tables with a reference to the UUID of that specific content type, with a collation of the metadata being stored in the respective artists
, albums
, and tracks
tables. This reduces the overall size of our database by not storing metadata per each path, and simplifies any logic that would be required for mounting, dismounting, or indexing Libraries on the fly. These paths get loaded in and we will iterate through them as part of our dedicated "get_path" functions that we have on the various structs, like koto_track_get_path
. At the moment, this will just iterate through each Library that the content is in and return the first hit, however the goal in the future is to:
- Prioritize local storage, even going so far as prioritizing local NVMe storage over HDDs when possible.
- Leverage our availability check to ignore any Libraries which are not currently available. This is especially useful for removable media devices.
- Finish the implementation of the artist page in the "no albums" scenario.
- Design and implement the user experience for audiobook listing, selection, and playback.
- Implement our 10-band equalizer and playback speed controls.