ocarina/design.txt

218 lines
5.5 KiB
Plaintext
Raw Normal View History

===============================================================================
= =
= Ocarina 6.0 =
= =
===============================================================================
My main goal for Ocarina 6.x is to plan out all of my actions before writing
code. In the past I was adding features as I thought of them before thinking
out how everything works together, and this made Ocarina difficult to maintain
because I had no overall plan. This document aims to fix that.
I will also create unit tests as I add features so bugs can be found faster.
Files:
ocarina/
design.txt
ocarina/gui/
ocarina/include/
group.h
library.h
playlist.h
ocarina/lib/
group.cpp
library.cpp
playlist.cpp
ocarina/tests/
$HOME/.ocarina{-debug}/
library/global.db
library/{0-X}
Database: (ocarina.db)
<Research FTS tables and inverted indexes for filtering>
Tags index -
<another FTS table>
Tag Name -> song ids
User settings -
create table if not exists config(
name PRIMARY KEY,
value INT,
);
Library: (lib/library.cpp)
This file will manage and control access to the library.
Album and artist information tables will be saved to a file in
library/global.db and can be shared across multiple library paths.
Internal:
struct Album {
unsigned int id;
string name;
short year;
};
vector<Album>;
struct Artist {
unsigned int id;
string name;
};
vector<Artist>
struct Genre {
unsigned int id;
string name;
};
vector<Genre>
struct Track {
unsigned int id;
unsigned int artist_id;
unsigned int album_id;
unsigned int genre_id;
bool valid;
string filepath;
string title;
string length_str;
short track;
short last_year;
short last_month;
short last_day;
unsigned int play_count;
unsigned int length;
};
class Library {
string base_path;
bool enabled;
bool valid;
vector<struct Track>
};
typedef struct trackid_t {
unsigned int library_id;
unsigned int track_id;
};
- API
/* Path management */
add_path_to_library(dir);
Add new row to paths table, update
rm_path_from_library(dir);
Remove row from paths table
update_path(dir);
Scan tracks table, remove paths that don't exist
Scan dir, add new files to database
Consider having SQLite create an index on tracks.filepath
update_all();
Call update_path() for each paths.dirpath
list_paths(list<>);
Tell the caller basic information about library paths
(dir, enabled, size,...)
Playlist: (lib/playlist.cpp)
A playlist is a simple list of songs that can be played either randomly
or in a user-defined order. It would probably be best to use a linked
list or vector to represent playlists, rather than creating a SQLite
table. I will be able to easily rearrange tracks in the playlist this
way. This will also make it easier to deal with playlist renames and
reordering by the user.
- API
/* Playlist management */
new_playlist();
del_playlist(playlist);
add_to_playlist(playlist, songid);
rm_from_playlist(playlist, songid);
playlist_size(playlist)
set_flag(playlist, flag)
- Flags
PL_ENABLED (1 << 0)
PL_RANDOM (1 << 1)
PL_DRAIN (1 << 2)
Groups: (lib/group.cpp)
Groups are going to be a new feature in Ocarina 6 and can compare
directly to Gmail-style labels. Ocarina 6 will create dynamic groups
that cannot be deleted by the user based on library status.
Default groups:
All music
All tracks are added to this group
Library
Banned Songs
These groups are mutually exclusive. A track is either
in the Library or the Banned Songs group
Unplayed tracks
Tracks with a play count of 0
- API
list_groups();
Return a list of group names
group_get_tracks(name):
Return a list of tracks that are in group "name"
Track.add_to_group(name);
Add a track to a group
Track.rm_from_group(name);
Remove a track from a group
- Design TODO <<<<<
- I need a way to loop over each track in the library to create
dynamic groups. Whole library iterator?
- A "Track" class with functions for accessing tags and with access
to groups. Perhaps make "Track" its own file, outside of the
library and group code?
Future work:
I want to set reasonable expectations for Ocarina 6 so that I don't
have to spend a large amount of time coding before releasing something
to the wild. This section will be a list of features that I want, but
should be deferred to a future release so basic support can be coded.
Hint: If feature B depends on A, implement A in 6.x and B in 6.x+1
- Categories: (6.1)
Use these to make "groups of groups" for better organization.
Different categories can include Album, Artist and Genere
dynamic groups in addition to user created groups (see below)
The Artist, Album and Genre "tables" can be used to populate
these categories.
- User created song groups: (6.2)
Basic add and remove features can be implemented using the
Library and Banned Songs groups. This will give me a chance
to test saving groups on a small scale before letting users
create anything they want.
- Save a user's playlist as a group: (6.2)
- Library defragment: (6.1)
Ocarina 6.0 will leave holes in the library when tracks are
deleted, potentially leading to fragmentation and larger-than-
needed file sizes. A "defragment" utility can be created to
clean up unused slots.
To help with fixing groups, a mapping of (old values) ->
(new values) should be kept.